How to limit endpoint access only to specific IPs with FastAPI?
You can also use --forwarded-allow-ips='127.0. 0.1,[::1]' to catch both ip4 and ip6 on localhost. --proxy-headers / --no-proxy-headers - Enable/Disable X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port to populate remote address info.
A Login IP Allowlist includes a range of IP addresses you define that indicates what IP addresses can access your account to prevent unauthorized IP addresses from logging into your account. Allowlisted IP addresses ranges can access the application.
FastAPI (Async) - Python FastAPI in asynchronous mode clocks in at ~228 requests per second.
Use the Request object directly For that you need to access the request directly. By declaring a path operation function parameter with the type being the Request FastAPI will know to pass the Request in that parameter. Note that in this case, we are declaring a path parameter beside the request parameter.
The accepted answer makes use of the TrustedHostMiddleware but that can be easily spoofed using a reverse proxy, i.e. using NGINX or using any other technique. In my opinion, validating IP address in a custom middleware is more secure:
from fastapi import FastAPI, Request, status
from fastapi.responses import JSONResponse
app = FastAPI()
# Whitelisted IPs
WHITELISTED_IPS = []
@app.middleware('http')
async def validate_ip(request: Request, call_next):
# Get client IP
ip = str(request.client.host)
# Check if IP is allowed
if ip not in WHITELISTED_IPS:
data = {
'message': f'IP {ip} is not allowed to access this resource.'
}
return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content=data)
# Proceed if IP is allowed
return await call_next(request)
I'd maintain a list of whitelisted IPs and then I'd compare the client IP to the list and will return a 400 Bad Request
error if the IP is not in the whitelisted IPs list.
FastAPI provides a TrustedHostMiddleware that:
Enforces that all incoming requests have a correctly set Host header, in order to guard against HTTP Host Header attacks.
from fastapi import FastAPI from fastapi.middleware.trustedhost import TrustedHostMiddleware app = FastAPI() app.add_middleware( TrustedHostMiddleware, allowed_hosts=["example.com","*.example.com"] ) @app.get("/") async def main(): return {"message": "Hello World"}
The following arguments are supported:
allowed_hosts
- A list of domain names that should be allowed as hostnames. Wildcard domains such as*.example.com
are supported for matching subdomains to allow any hostname either useallowed_hosts=["*"]
or omit the middleware.If an incoming request does not validate correctly then a 400 response will be sent.
Another solution would be to compose an IP whitelist for your deployment medium (ex: k8).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With