Skip to content

fix(publisher): allow cross-origin media in the published CSP - #354

Open
mostafasadeghidev wants to merge 1 commit into
CoreBunch:mainfrom
mostafasadeghidev:fix/allow-external-media-in-published-csp
Open

fix(publisher): allow cross-origin media in the published CSP#354
mostafasadeghidev wants to merge 1 commit into
CoreBunch:mainfrom
mostafasadeghidev:fix/allow-external-media-in-published-csp

Conversation

@mostafasadeghidev

Copy link
Copy Markdown

What

The base CSP now sets media-src 'self' data: https:, mirroring img-src.

Why

createBaseCspPlan set img-src 'self' data: https: but no media-src. An unset media-src falls back to default-src 'self', so every published page would load a remote image happily and refuse every remote <video> / <audio>:

Loading media from 'https://…/hover.mp4' violates the following Content
Security Policy directive: "default-src 'self'". Note that 'media-src' was
not explicitly set, so 'default-src' is used as a fallback. The action has
been blocked.

Both directives govern passive references that execute nothing, so the line between them was arbitrary. Allowing a remote image while blocking a remote video isn't a security posture, it's an omission.

It is also invisible from the markup, which is what makes it expensive to find. The element is correct, the URL resolves, the file serves with 206 video/mp4 — the video simply never plays, and only the browser console says why. I found it by reading the published bytes, confirming the media URL was fine, and then checking the console.

How

One directive, same sources as img-src.

The test asserts the two directives are equal to each other rather than pinning the literal string a second time — so if img-src is ever tightened or relaxed, the test points at the divergence instead of silently passing.

User impact

Relaxes one directive for published pages. No effect on script-src, which is what actually gates code execution and stays 'self'. Sites that host all their media locally are unaffected — 'self' was already permitted.

Verification

bun test src/__tests__/publisher/   # 413 pass
bun run build
bun run lint

The existing byte-identical-policy test in cspPlan.test.ts was updated for the new directive (it pins the full serialized string), plus one new test covering the img/media parity.

Verified end-to-end: on a real published page, four cross-origin <video> elements went from CSP-blocked to playing, with no other console errors introduced.

The base policy set `img-src 'self' data: https:` but never set
`media-src`. An unset `media-src` falls back to `default-src 'self'`, so
every published page loaded a remote image happily and refused every
remote `<video>` / `<audio>`:

    Loading media from 'https://…/hover.mp4' violates the following
    Content Security Policy directive: "default-src 'self'". Note that
    'media-src' was not explicitly set, so 'default-src' is used as a
    fallback. The action has been blocked.

Both directives govern passive references that execute nothing, so the
line between them was arbitrary — and invisible from the markup. The
element is right, the URL resolves, the file serves; the video just never
plays and only the console says why.

`media-src` now mirrors `img-src` exactly, and a test asserts they stay
equal rather than pinning the literal string twice.

Found on a site imported from another builder, where per-item hover
videos are served from the source CDN.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant