Repository navigation
fix(share-worker): harden sweep, uploads, and content CSP - #71
Merged
Merged
Conversation
Addresses GHSA-j65f-2wm8-5r8g and GHSA-cfx9-rjc2-c87c, plus the non-object create body from #68. - Sweep only treats capsules/<32 hex>/_meta.json as a record and takes the id from the key, not the object body. Names under media/ starting with "_" are refused. - Uploads answer 409 unless the capsule is still in the uploading state. - media/ accepts only image names (jpg, jpeg, png, gif, webp, avif). - content.html allows its lightbox script by sha256 instead of 'unsafe-inline', and sets form-action 'none'. A test recomputes the hash from the userscript's emitted HTML. - Upload bodies are counted while streaming and cut off at the remaining capsule budget. - New per-capsule UPLOAD_LIMITER binding; the create limiter keys IPv6 clients on their /64. - A JSON body that is not an object returns 400 instead of throwing. Refs #68 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 7, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the confirmed defects behind GHSA-j65f-2wm8-5r8g and GHSA-cfx9-rjc2-c87c, plus the non-object create body from #68 (refs #68, does not close it).
Changes
capsules/<32 hex>/_meta.jsoncounts as a record, and the id comes from the key, never the object body. Upload names undermedia/starting with_are refused.PUTanswers 409 unless the capsule isuploading. A published capsule is immutable; a leaked token can still delete it.media/accepts onlyjpg|jpeg|png|gif|webp|avif. The client uploads nothing else for a share (images and video poster stills).content.html,content.mdandmanifest.jsonare unchanged.content.htmluses a sha256script-srcfor the lightbox script instead of'unsafe-inline', and addsform-action 'none'. Across the whole history ofsourcecapsule.user.js(69 revisions, all since v0.5.0) the script text has exactly one variant, so one hash covers every capsule made by an older client. A test recomputes the hash from the current userscript's emitted HTML, so a future lightbox edit fails CI.UPLOAD_LIMITER(120 per 60 s, keyed on capsule id, checked after the bearer token so strangers cannot spend a capsule's budget). The create limiter now keys IPv6 on the /64 prefix.nullor any non-object JSON returns a JSON 400 instead of throwing.Deploy note
share-worker/wrangler.tomladds aUPLOAD_LIMITERrate-limit binding (namespace_id = "1002"). It is picked up onwrangler deploy; the code is a no-op when the binding is absent.Behaviour changes
.svgor unknown-type (.bin) media now get 400.mimeToExtemits these only for SVG or non-image data, which X media does not produce.Tests
One focused block per item in
test/share-worker.test.mjs.npm run lint,format:check,test:shareandnpm testpass locally.🤖 Generated with Claude Code