#116 Pages inbox quota stops checking at 1000 objects; rate map has no hard cap
Problem
The Pages inbox quota is only checked against the first 1000 R2 objects. overQuota calls bucket.list({ limit: Math.min(limit, 1000) }) once; if INBOX_QUOTA is above 1000, submissions keep being stored after the limit because the returned list can never reach the configured quota.
Verified with the real onRequestPost and a fake bucket containing 1001 objects, INBOX_QUOTA=1500:
status 200 stored 1002
Expected 503. functions/inbox/[kind].js:276-279.
The isolate-local rate-limit map also has no hard cap: it only prunes expired entries when size > 10000, so an attacker rotating source IPs can keep growing it. Cloudflare's WAF rule is the documented durable control, but the in-function map should still fail closed at a fixed key limit like serve's RATE_MAX_KEYS (f0rge #65).
Fix
- Paginate
bucket.listwithcursoruntillimitobjects are counted or the list ends. - Add a hard
MAX_KEYScheck for new rate-limit keys after the expiry sweep. - Add Node tests for quota 1500 and the rate-map cap.
Uunknown ·
Fixed in PR #61 (
3df93c3a-bd5e-43f4-bb73-0f3dd886eeb1, commitee6e71b, mergede834a46). CI2026-10-27T19-50-04.907798288Zpassed; Node tests 11/11.overQuotanow paginates R2listcursors until the configured limit is counted (fails closed on a truncated page without a cursor); the isolate rate map fails closed for a new key atMAX_RATE_KEYSafter the expiry sweep. Added a 1500-object quota regression.