blob: aa8344a1aa5f7a4b8bb3bd0f5d6d234b2b3e9a00 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
"""
Client address resolution for the audit log and rate limiting.
Finding M7: every call site did
fwd = request.headers.get("X-Forwarded-For")
return fwd.split(",")[0].strip() if fwd else request.client.host
which trusts a header the client controls. Anyone could forge the IP written into
the compliance log — the log that exists specifically to answer legal requests —
and sidestep per-IP rate limiting at the same time.
X-Forwarded-For is only consulted when the immediate peer is a trusted proxy, and
then the *rightmost* entry is used: that is the one our own proxy appended, whereas
the leftmost is whatever the client sent.
"""
from fastapi import Request
# Caddy terminates TLS on the same host and proxies to 127.0.0.1:8000.
TRUSTED_PROXIES = frozenset({"127.0.0.1", "::1", "localhost"})
def client_ip(request: Request) -> str:
peer = request.client.host if request.client else ""
if peer in TRUSTED_PROXIES:
forwarded = request.headers.get("X-Forwarded-For")
if forwarded:
hops = [h.strip() for h in forwarded.split(",") if h.strip()]
if hops:
return hops[-1]
return peer or "unknown"
|