Security Notes
Notes from the exploratory security pass on palette-dev (2026-09-09). No issues remain open from these findings; this page records the verified behavior and known tradeoffs.
Rate limiting
Bucket key and header spoofing (verified, #144)
The create rate limiter is keyed on clientIP, which takes the rightmost entry in X-Forwarded-For (the address of the immediate peer as seen by the trusted proxy layer). This means:
- Spoofed
X-Forwarded-For, X-Real-Ip, and True-Client-Ip headers cannot bypass or poison the bucket.
- Verified on palette-dev: six rapid
POST /api/pastes from one IP gave 201 x5 then 429; repeating while sending X-Forwarded-For: 1.2.3.4, X-Real-Ip: 9.9.9.9, and True-Client-Ip: 3.3.3.3 still returned 429 for every request (no bypass).
Create budget
- Budget per IP: burst of 5 creates, refilled at 1 request/second.
- Sixth rapid create from the same IP gets
429 Too Many Requests.
Known inherent limitation: shared egress IP
The limiter is keyed solely by IP, so clients behind a single egress address — an office NAT, a VPN exit node, a CGNAT carrier — share one create bucket. One heavy user can consume the burst-5 budget and cause 429 responses for everyone behind that IP. This is an inherent tradeoff of IP-keyed limiting, accepted for now; alternatives (auth-scoped or cookie-scoped buckets) would be a design change and have not been scheduled.