Fix: Prefer X-Real-IP over XFF[0] in get_client_ip to close spoof bypass
XFF[0] is attacker-controllable; a crafted X-Forwarded-For header could attribute login failures to a victim IP, triggering their lockout while the attacker accumulates none. ingress-nginx sets X-Real-IP via its realip module using an authoritative CIDR allowlist and overwrites any client-supplied value, making it spoof-resistant. Fallback to XFF[0] is retained for defence in depth but now emits a warning if reached. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -80,10 +80,17 @@ def test_get_client_ip_no_trusted_networks_returns_peer():
|
||||
assert get_client_ip(req, []) == "203.0.113.1"
|
||||
|
||||
|
||||
def test_get_client_ip_trusted_peer_uses_xff():
|
||||
req = make_request("10.0.0.1", {"X-Forwarded-For": "203.0.113.5"})
|
||||
def test_get_client_ip_trusted_peer_uses_real_ip():
|
||||
req = make_request("10.0.0.1", {"X-Real-IP": "203.0.113.9"})
|
||||
nets = [ipaddress.ip_network("10.0.0.0/8")]
|
||||
assert get_client_ip(req, nets) == "203.0.113.5"
|
||||
assert get_client_ip(req, nets) == "203.0.113.9"
|
||||
|
||||
|
||||
def test_get_client_ip_real_ip_wins_over_xff():
|
||||
# Regression: spoofed XFF must not override nginx-set X-Real-IP.
|
||||
req = make_request("10.0.0.1", {"X-Real-IP": "203.0.113.9", "X-Forwarded-For": "1.2.3.4"})
|
||||
nets = [ipaddress.ip_network("10.0.0.0/8")]
|
||||
assert get_client_ip(req, nets) == "203.0.113.9"
|
||||
|
||||
|
||||
def test_get_client_ip_untrusted_peer_ignores_xff():
|
||||
@@ -92,7 +99,7 @@ def test_get_client_ip_untrusted_peer_ignores_xff():
|
||||
assert get_client_ip(req, nets) == "8.8.8.8"
|
||||
|
||||
|
||||
def test_get_client_ip_trusted_peer_falls_back_to_real_ip():
|
||||
req = make_request("10.0.0.1", {"X-Real-IP": "203.0.113.9"})
|
||||
def test_get_client_ip_trusted_peer_falls_back_to_xff_when_no_real_ip():
|
||||
req = make_request("10.0.0.1", {"X-Forwarded-For": "203.0.113.5"})
|
||||
nets = [ipaddress.ip_network("10.0.0.0/8")]
|
||||
assert get_client_ip(req, nets) == "203.0.113.9"
|
||||
assert get_client_ip(req, nets) == "203.0.113.5"
|
||||
|
||||
Reference in New Issue
Block a user