Repository navigation
fix(edge): bound import-source and share requests - #116
Conversation
import-source now keeps one 10-second deadline from DNS through the last body byte, so a slow sender is cut off instead of holding the function open. Resolved addresses are checked against the full IANA special-purpose lists, including NAT64, benchmarking, multicast and reserved space. share now caps the request at 512 KB, accepts expiries of 1 to 90 days (30 when omitted), and reserves a "share" daily quota of 50 per user through consume_daily_quota. The DNS pinning gap that the runtime cannot close is recorded as an exception in docs/standards/security.md, pending Adam's decision. Closes findings [4], [7] and [10] of the 2026-08-19 security review. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reachedEnable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. Next included review available in 36 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (14)
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing. Comment |
import-source now reads its own request body with a 16 KB cap under the same deadline, so a stalled upload gets a 408 instead of holding the function open and then reporting a misleading source timeout. Adds 100:0:0:1::/64 to the blocked IPv6 ranges. Replaces the importer source-string assertions with behavior tests for the byte cap at its exact boundary and the one-day share expiry. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Codex review round 1 (at 717f41d): five findings.
Local at 72af855: |
|
Deployed to production from 6ec1a65, which also contains the follow-up #118. Staging verification found that the hosted runtime holds a response until the request body has been read, so oversized requests waited about 150 s for their 413. #118 fixes that.
|
Closes the three findings still open from the 2026-08-19 security review: [4], [7] and [10]. The other eight are already fixed on
main.What changes
64:ff9b::/96and64:ff9b:1::/48), 6to4, Teredo and the other IPv6 special blocks. IPv4-mapped IPv6 addresses are now checked in hex form too.expiresInDaysmust be a whole number from 1 to 90 (400 otherwise). Each user can create 50 shares a day, enforced through the existing atomicconsume_daily_quotaRPC under a newsharekey (429 with the samecode/limit/currentfields as import-source). Malformed JSON now gets a 400 instead of a 500.No migration:
consume_daily_quotaalready accepts any quota key.Defaults to check
expiresInDaysused to be permanent. It now expires after 30 days, because an upper bound means nothing if leaving the field out still gives a permanent link. Nothing insrc/calls thesharefunction today, so no client changes. Existing shares keep their current expiry.Needs Adam's sign-off
The runtime cannot pin a fetch to the address it checked, so a DNS answer that changes between the check and the connection is not covered. This PR records that as an accepted exception in
docs/standards/security.mdunder "Recorded exceptions" and marks it as needing Adam's decision. Closing it fully needs an egress proxy outside the Edge runtime.Verification
Local only. Every GitHub Actions job was refused for billing ("recent account payments have failed"), so there is no CI run on this head.
npm run test:edge333/333,npm test272/272, lint, typecheck anddocs:checkall pass.npm run verifypassed at 717f41d, including build and the Chromium smoke run (29 passed).import-sourceandsharehandlers ran underdeno run, with only Supabase auth and REST stubbed:198.18.0.1,224.0.0.1and192.0.0.1got a 400 before any connection.expiresInDays91 got a 400 and 90 was accepted, and the 51st share of the day got a 429.verify-debatelabrecipes and the DB gate. The shared Supabase stack was busy with another PR's two-hour agentic run. No SQL changed, and thesharequota key reusesconsume_daily_quota, whichdaily_usage_quota_test.sqlalready covers. Staging gets the full-stack check after merge, before production.🤖 Generated with Claude Code