Fixes the security issue where realIP() unconditionally trusts X-Real-IP and X-Forwarded-For headers from any client, allowing attackers to bypass the login rate limiter by spoofing headers.
Changes
realIP() now parses RemoteAddr and only trusts proxy headers when the source IP is RFC1918 (10/8, 172.16/12, 192.168/16), loopback (127/8), or IPv6 ULA/loopback
Public source IPs have headers ignored — fail closed, uses RemoteAddr
Added isTrustedProxy() helper with pre-parsed CIDR nets
Updated tests to cover both trusted proxy (headers honoured) and untrusted proxy (headers ignored) scenarios
## Summary
Fixes the security issue where `realIP()` unconditionally trusts `X-Real-IP` and `X-Forwarded-For` headers from any client, allowing attackers to bypass the login rate limiter by spoofing headers.
## Changes
- `realIP()` now parses `RemoteAddr` and only trusts proxy headers when the source IP is RFC1918 (10/8, 172.16/12, 192.168/16), loopback (127/8), or IPv6 ULA/loopback
- Public source IPs have headers ignored — fail closed, uses `RemoteAddr`
- Added `isTrustedProxy()` helper with pre-parsed CIDR nets
- Updated tests to cover both trusted proxy (headers honoured) and untrusted proxy (headers ignored) scenarios
- Added `TestIsTrustedProxy` unit test
(closes #44)
sneak
was assigned by clawbot2026-02-16 07:02:14 +01:00
realIP() now parses RemoteAddr and checks if the source IP is in
RFC1918 (10/8, 172.16/12, 192.168/16), loopback (127/8), or IPv6
ULA/loopback ranges before trusting X-Real-IP or X-Forwarded-For
headers. Public source IPs have headers ignored (fail closed).
This prevents attackers from spoofing X-Forwarded-For to bypass
the login rate limiter.
✅ No new issues. One pre-existing testpackage lint warning in internal/handlers/tail_validation_test.go (unrelated to this PR).
## CI Results
### Tests (`make test`)
✅ All packages pass.
### Lint (`golangci-lint run ./...`)
✅ No new issues. One pre-existing `testpackage` lint warning in `internal/handlers/tail_validation_test.go` (unrelated to this PR).
sneak
merged commit c4c62c9aba into main2026-02-16 07:03:23 +01:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Fixes the security issue where
realIP()unconditionally trustsX-Real-IPandX-Forwarded-Forheaders from any client, allowing attackers to bypass the login rate limiter by spoofing headers.Changes
realIP()now parsesRemoteAddrand only trusts proxy headers when the source IP is RFC1918 (10/8, 172.16/12, 192.168/16), loopback (127/8), or IPv6 ULA/loopbackRemoteAddrisTrustedProxy()helper with pre-parsed CIDR netsTestIsTrustedProxyunit test(closes #44)
CI Results
Tests (
make test)✅ All packages pass.
Lint (
golangci-lint run ./...)✅ No new issues. One pre-existing
testpackagelint warning ininternal/handlers/tail_validation_test.go(unrelated to this PR).