Fix #280 follow-up: remove PALETTE_TRUSTED_IP_HEADER
Per owner decision the optional proxy-header escape hatch is dead config: remove the env var, its plumbing (Config.TrustedIPHeader, SetTrustedIPHeader), and the README row. Rate-limit keying is always the peer address; no client-supplied IP header is ever trusted. Tests updated to assert headers (CF-Connecting-IP included) never influence clientIP.
This commit is contained in:
@@ -7,48 +7,18 @@
|
||||
// per request and the limit was unenforceable (pentest H1: 6x201 across 8
|
||||
// rotating-XFF creates).
|
||||
//
|
||||
// Default: key on the actual peer address (RemoteAddr) only. Behind any
|
||||
// The bucket key is always the actual peer address (RemoteAddr). Behind any
|
||||
// reverse proxy this is the proxy's address, so all clients share one bucket
|
||||
// per endpoint — coarse, but safe.
|
||||
//
|
||||
// Proxy-honoring mode: a deployment in front of a proxy that OVERWRITES (not
|
||||
// appends to) a client-IP header can set PALETTE_TRUSTED_IP_HEADER (e.g.
|
||||
// CF-Connecting-IP when Cloudflare is the ingress; Cloudflare strips any
|
||||
// client-supplied value). The header is honored ONLY when explicitly
|
||||
// configured at startup, and X-Forwarded-For / X-Real-Ip are never trusted.
|
||||
// per endpoint — coarse, but safe. Client-supplied IP headers
|
||||
// (X-Forwarded-For, X-Real-Ip, and any others) are never trusted.
|
||||
package api
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
trustedIPMu sync.RWMutex
|
||||
trustedIPHeader string // empty = never trust any client-IP header
|
||||
)
|
||||
|
||||
// SetTrustedIPHeader configures the single proxy-controlled header whose
|
||||
// value may key rate-limit buckets. Called at startup; tests may reset it.
|
||||
func SetTrustedIPHeader(name string) {
|
||||
trustedIPMu.Lock()
|
||||
defer trustedIPMu.Unlock()
|
||||
trustedIPHeader = name
|
||||
}
|
||||
|
||||
func getTrustedIPHeader() string {
|
||||
trustedIPMu.RLock()
|
||||
defer trustedIPMu.RUnlock()
|
||||
return trustedIPHeader
|
||||
}
|
||||
|
||||
func clientIP(r *http.Request) string {
|
||||
if name := getTrustedIPHeader(); name != "" {
|
||||
if v := r.Header.Get(name); v != "" {
|
||||
return v
|
||||
}
|
||||
}
|
||||
host := r.RemoteAddr
|
||||
if h, _, err := net.SplitHostPort(r.RemoteAddr); err == nil {
|
||||
host = h
|
||||
|
||||
Reference in New Issue
Block a user