Add rate-limits page (anti-spoofing verification, shared egress IP tradeoff, issue 144)
+18
@@ -0,0 +1,18 @@
|
||||
# Rate Limits
|
||||
|
||||
Palette rate limits paste creation per client IP: burst of 5, then 1 request per second. Exceeding it returns `429` with a `Retry-After` header (see [API](API.md)).
|
||||
|
||||
## Client IP resolution
|
||||
|
||||
`clientIP` takes the **rightmost** entry in `X-Forwarded-For`, i.e. the address added by the trusted reverse proxy in front of Palette. This means spoofed forwarding headers cannot bypass or poison the rate-limit bucket.
|
||||
|
||||
Verified against palette-dev (2026-09-09, issue #144):
|
||||
|
||||
1. Six rapid `POST /api/pastes` from one IP: `201` x5, then `429`.
|
||||
2. Repeated while sending spoofed headers `X-Forwarded-For: 1.2.3.4`, `X-Real-Ip: 9.9.9.9`, `True-Client-Ip: 3.3.3.3`: all requests still received `429`. No bypass, and the spoofed values did not shift the bucket.
|
||||
|
||||
## Known tradeoff: shared egress IPs
|
||||
|
||||
Because the bucket is keyed solely by client IP, everyone behind one egress IP (office network, VPN, carrier NAT) shares a single burst-5 / 1rps create budget. One heavy user can rate-limit everyone behind that IP.
|
||||
|
||||
This is an inherent property of IP-keyed limiting without accounts, accepted for now. If it becomes a real problem, candidate mitigations include raising the create budget or adding per-session (cookie) buckets on top of the IP bucket.
|
||||
Reference in New Issue
Block a user