Skip to content

fix: exempt loopback from TierAuth so local vault run doesn't get 429'd

f2f2256
Select commit
Loading
Failed to load commit list.
Merged

fix: exempt loopback from TierAuth so local vault run doesn't get 429'd #97

fix: exempt loopback from TierAuth so local vault run doesn't get 429'd
f2f2256
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed Apr 21, 2026 in 11m 4s

Code review found 2 important issues

Found 5 candidates, confirmed 3. See review comments for details.

Details

Severity Count
🔴 Important 2
🟡 Nit 0
🟣 Pre-existing 0
Severity File:Line Issue
🔴 Important internal/server/server.go:847-849 ipKeyer loopback exemption removes rate limiting from register, forgot-password, and resend-verification
🔴 Important internal/ratelimit/key.go:29-37 IPKeySkipLoopback uses XFF-derived IP, enabling loopback spoofing to bypass all ipAuth limits when AGENT_VAULT_TRUSTED_P

Annotations

Check failure on line 849 in internal/server/server.go

See this annotation in the file changed.

@claude claude / Claude Code Review

ipKeyer loopback exemption removes rate limiting from register, forgot-password, and resend-verification

The PR's loopback exemption in `ipKeyer()` (server.go:847-849) is overly broad: it bypasses TierAuth for ALL routes using `ipAuth`, not just the four static reads that motivated the change. The PR description claims 'Login/register still enforce their own in-handler buckets directly on the raw IP,' but this is only true for `handleLogin` (handle_auth.go:594-596); `handleRegister`, `handleForgotPassword`, `handleResendVerification`, `handleResetPassword`, and `handleVerify` have NO in-handler IP 

Check failure on line 37 in internal/ratelimit/key.go

See this annotation in the file changed.

@claude claude / Claude Code Review

IPKeySkipLoopback uses XFF-derived IP, enabling loopback spoofing to bypass all ipAuth limits when AGENT_VAULT_TRUSTED_PROXIES is set

The new IPKeySkipLoopback function checks the XFF-derived clientIP() result for loopback rather than the actual TCP connection address (r.RemoteAddr); when AGENT_VAULT_TRUSTED_PROXIES is set and the proxy is misconfigured to forward client-supplied XFF verbatim (nginx proxy_set_header X-Forwarded-For $http_x_forwarded_for), an attacker can send X-Forwarded-For: 127.0.0.1 and clientIP() returns 127.0.0.1, causing IPKeySkipLoopback to return "" and the rate-limit middleware to fail open. The fix i