fix: per-IP auth rate limiting instead of one global bucket
A single global token bucket let one attacker at the sustained rate 429 every user's login/register/change-password. Key buckets by client IP: the SvelteKit proxy now stamps the real peer address onto X-Forwarded-For (overriding any client-supplied value, anti-spoof), and axum reads it via a ClientIp extractor — but only when AUTH_TRUSTED_PROXY is set, else it falls back to the shared bucket (today's behavior). The per-IP map is bounded (10k IPs, idle buckets pruned) so a spoofed-IP spray can't grow it. AUTH_TRUSTED_PROXY defaults false (safe for a directly-exposed backend); compose sets it true since the proxy is the single trusted hop. Bump to 0.124.12. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,14 @@ pub struct AuthConfig {
|
||||
/// so a private instance is locked down with a single switch.
|
||||
/// Defaults to `false` (current public behaviour).
|
||||
pub private_mode: bool,
|
||||
/// Whether to trust a proxy-supplied `X-Forwarded-For` header as the
|
||||
/// client IP for per-IP auth rate limiting. Enable ONLY when the backend
|
||||
/// sits behind a trusted reverse proxy that overrides the header (the
|
||||
/// compose deploy: SvelteKit's hooks.server.ts sets it from the real peer
|
||||
/// address). When `false` (default), the header is ignored and the auth
|
||||
/// limiter uses a single shared bucket — a directly-exposed backend must
|
||||
/// keep this off or clients could spoof their IP to dodge the limit.
|
||||
pub trusted_proxy: bool,
|
||||
}
|
||||
|
||||
impl Default for AuthConfig {
|
||||
@@ -42,6 +50,7 @@ impl Default for AuthConfig {
|
||||
rate_limit: crate::auth::rate_limit::RateLimitConfig::default(),
|
||||
allow_self_register: true,
|
||||
private_mode: false,
|
||||
trusted_proxy: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -584,6 +593,7 @@ impl Config {
|
||||
},
|
||||
allow_self_register: env_bool("ALLOW_SELF_REGISTER", true),
|
||||
private_mode: env_bool("PRIVATE_MODE", false),
|
||||
trusted_proxy: env_bool("AUTH_TRUSTED_PROXY", false),
|
||||
},
|
||||
upload: UploadConfig {
|
||||
max_request_bytes: env_usize("MAX_REQUEST_BYTES", 200 * 1024 * 1024),
|
||||
|
||||
Reference in New Issue
Block a user