Owner follow-up to the #280 fix (PR #284): the trusted-header env var is gone. clientIP() now uses the peer address exclusively and ignores all client-supplied IP headers; the env var row is removed from the README.
51 lines
1.7 KiB
Go
51 lines
1.7 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
func TestClientIPUsesRemoteAddrNotXFF(t *testing.T) {
|
|
r := httptest.NewRequest("POST", "/api/pastes", nil)
|
|
r.RemoteAddr = "203.0.113.7:4432"
|
|
r.Header.Set("X-Forwarded-For", "1.2.3.4, 1.2.3.5, 203.0.113.9")
|
|
r.Header.Set("X-Real-Ip", "203.0.113.10")
|
|
if got := clientIP(r); got != "203.0.113.7" {
|
|
t.Fatalf("clientIP = %q, want peer 203.0.113.7", got)
|
|
}
|
|
}
|
|
|
|
// A proxy-controlled header is not honored even when set: #280 revision
|
|
// removed the PALETTE_TRUSTED_IP_HEADER mechanism per owner decision, so the
|
|
// bucket key is the peer address only.
|
|
func TestClientIPNeverTrustsHeaders(t *testing.T) {
|
|
r := httptest.NewRequest("POST", "/api/pastes", nil)
|
|
r.RemoteAddr = "10.0.1.47:9999"
|
|
r.Header.Set("CF-Connecting-IP", "198.51.100.9")
|
|
if got := clientIP(r); got != "10.0.1.47" {
|
|
t.Fatalf("clientIP = %q, want peer 10.0.1.47", got)
|
|
}
|
|
}
|
|
|
|
// Issue #280: rotating X-Forwarded-For must NOT reset the bucket. Pentest
|
|
// repro was 8 creates with rotating XFF -> 6x201.
|
|
func TestRotatingXFFDoesNotResetBucket(t *testing.T) {
|
|
globalLimiter = newLimiter()
|
|
s := defaultSettings(Config{}) // burst/limit defaults; header values are ignored anyway
|
|
var allowed, limited int
|
|
for i := 0; i < 8; i++ {
|
|
r := httptest.NewRequest("POST", "/api/pastes", nil)
|
|
r.RemoteAddr = "198.51.100.1:5000"
|
|
r.Header.Set("X-Forwarded-For", fmt.Sprintf("9.9.9.%d", i))
|
|
if rateLimitCreate(r, s) {
|
|
allowed++
|
|
} else {
|
|
limited++
|
|
}
|
|
}
|
|
if float64(allowed) != s.RateLimitBurst || limited != 8-int(s.RateLimitBurst) {
|
|
t.Fatalf("rotating XFF: allowed=%d limited=%d, want allowed=%v (burst), limited=%d", allowed, limited, s.RateLimitBurst, 8-int(s.RateLimitBurst))
|
|
}
|
|
}
|