extract_client_ip trusts X-Forwarded-For from any peer (spoofing risk with IP auto-login) #32
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_proxy#32
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
extract_client_ip(incrates/hero_proxy_server/src/proxy.rs) honorsX-Real-IpandX-Forwarded-Forfrom any source, with no validation that the immediate peer is a trusted upstream proxy. With IP auto-login (user_networks) active, this means anyone who can reach a hero_proxy listener directly can spoof their source IP viaX-Forwarded-Forand impersonate whatever user that IP is mapped to.Severity
High once IP auto-login is wired up (currently broken for direct connections — see #31 for the fix that makes it work, which is what surfaces this gap operationally). Concrete attack:
This pre-dates the peer-addr fallback fix (the trust gap was always there) but was operationally invisible because IP-auto-login itself was broken from browser → proxy.
Fix shape
Add a
trusted_proxiessetting (DB column onsettingstable or env var):trusted_proxies = [](default) → edge mode. IgnoreX-Real-IpandX-Forwarded-Forentirely. Only use TCP peer addr.trusted_proxies = [10.0.0.0/8, ...]→ behind-CDN mode. HonorX-Real-Ip/X-Forwarded-ForONLY when the immediate peer (TCP source) is in that list.Standard pattern — matches nginx's
set_real_ip_from, Cloudflare's trusted IP ranges, tower-http'sRealIpmiddleware design.Implementation:
Plus admin UI for managing the trusted list.
Backward compat
trusted_proxies. One-time setup per deployment.X-Forwarded-Foris silently ignored, peer addr always wins. Most secure default.