fix(security): trusted-proxy-scoped login rate limit
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
@@ -111,6 +112,26 @@ func TestLoginMe(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 伪造 XFF 换不了限流桶: peer(192.0.2.1)不在可信代理段 → ClientIP 取 peer,XFF 忽略
|
||||
func TestLoginRateLimitResistsXFFSpoof(t *testing.T) {
|
||||
if os.Getenv("REDIS_URL") == "" {
|
||||
t.Skip("REDIS_URL not set (no redis → IncrWindow always allows)")
|
||||
}
|
||||
_, _, h, _ := setupAPI(t) // setupAPI 已重置 loginrl:192.0.2.1
|
||||
for i := 1; i <= 6; i++ {
|
||||
req := httptest.NewRequest("POST", "/api/auth/login", bytes.NewBufferString(`{"username":"alice","password":"nope"}`))
|
||||
req.Header.Set("X-Forwarded-For", fmt.Sprintf("203.0.113.%d", i))
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if i < 6 && w.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("attempt %d: want 401 got %d %s", i, w.Code, w.Body)
|
||||
}
|
||||
if i == 6 && w.Code != http.StatusTooManyRequests {
|
||||
t.Fatalf("attempt 6: spoofed XFF escaped per-peer limit: want 429 got %d", w.Code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMemberCannotWriteUsers(t *testing.T) {
|
||||
_, _, h, _ := setupAPI(t)
|
||||
w := do(h, "POST", "/api/auth/login", "", map[string]string{"username": "bob", "password": testPW})
|
||||
|
||||
Reference in New Issue
Block a user