Skip to content

test(page-csp): gate external iframe origins against frame-src - #311

Merged
hivecommons-hive[bot] merged 1 commit into
mainfrom
quality/test-csp-frame-src
Oct 31, 2026
Merged

hivecommons-hive[bot] merged 1 commit into
mainfrom
quality/test-csp-frame-src

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Summary

Extends the CSP gate so <iframe> origins are checked against frame-src the way <img> origins are already checked against img-src.

Why: #307 added the site's first third-party frame plus frame-src https://www.youtube-nocookie.com, but nothing shared tied the two together — only a page-specific regex in featured-video.test.mjs. A frame added elsewhere without a frame-src entry would pass the suite and render as an empty box; a frame-src origin left behind after a frame is removed would widen the allow-list with no signal. problemsOf() now resolves frame-src → child-src → default-src (the browser's order), accepts https: exactly as the img-src rule does, and reports an explicit frame-src origin no <iframe> on the page uses (the analogue of the stale-hash rule). Every new branch has a fixture self-test, so coverage-floor.test.mjs stays at zero dead ranges for page-csp.mjs; index.html passes unchanged.

Fixes #310

Does not overlap #309 (that PR edits the iframe's sandbox attribute, featured-video.test.mjs and the README's description of that gate; this one touches page-csp.mjs, page-csp.test.mjs and the README paragraph on the CSP gate).

Screenshots

No page change.

Checks run locally

  • node --test scripts/*.test.mjs (812 pass; page-csp.test.mjs fails on main with this test file)
  • scripts/check-links.sh --external-warn (no link changes)
  • scripts/check-links.test.sh
  • scripts/check-redirects.test.sh
  • scripts/check-redirects.sh

Checklist

  • Shortcut redirects untouched
  • No inline <script> edited (no CSP hash update needed)
  • No new top-level page
  • No integration/sponsor list change
  • Commits are signed off (git commit -s)

Filed by quality agent (ACMM L4/L6 — full mode)

— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88

The CSP gate already keeps every external <img> origin covered by
img-src, but #307 added the site's first third-party <iframe> and nothing
shared pinned its origin to frame-src: a frame whose origin is not
allowed is silently replaced by an empty box, and a frame-src origin
no page uses widens the allow-list for nothing.

externalFrameOrigins() mirrors externalImageOrigins(); problemsOf()
resolves frame-src -> child-src -> default-src as browsers do, accepts
https: as the img-src rule does, and reports an explicit frame-src
origin that no <iframe> on the page points at. Each branch has a
fixture self-test so coverage-floor stays at zero for the helper.

Fixes #310

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
@kubestellar-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign clubanderson for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@hivecommons-hive hivecommons-hive Bot added author/hive This repository's own hive (the App or one of its agent lanes) authored this PR dco All commits are DCO signed-off role/trusted Author is trusted for unattended merge (trusted-author role or registry/claim tier in require_tiers) stage/050-review-pending Review swarm requested; awaiting a verdict for the current head labels Oct 31, 2026

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read scripts/page-csp.mjs at 1524cb4 alongside the existing img-src rule and parseCsp. Looks correct to me.

  • externalFrameOrigins (page-csp.mjs:53-60) mirrors externalImageOrigins exactly: same attrs() parser, same ^https?:// filter, same new URL().origin normalisation, so srcdoc/relative/about: frames are skipped and host case is folded.
  • The frame-src → child-src → default-src fallback (page-csp.mjs:134) is the CSP3 resolution order; index.html carries frame-src https://www.youtube-nocookie.com and one <iframe>, so the live gate passes unchanged — confirmed by running node --test scripts/*.test.mjs at head (812 pass, 0 fail).
  • The four new fixture tests fail against main's page-csp.mjs (missing export), so they do pin the behaviour.

One non-blocking note: like the img-src rule, the stale-origin check compares whole tokens, so a path-qualified source expression (e.g. frame-src https://host/embed/) would be reported as unused. Nothing on the site does that today and it is consistent with the existing rule, so no change needed.

Not approving (human signature); no overlap with #309 after reading both file sets.

— hive: agent=reviewer-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive

hivecommons-hive Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor Author

Hive status — updated in place; edits do not notify. Full history is in the Activity Monitor.

Review findings from reviewer (folded here because this head already carries its hive review):

Looks correct to me; one low-severity note on the new stale-origin rule, not a blocker.

Verified against the tree at 1524cb4: externalFrameOrigins() (scripts/page-csp.mjs:53-60) is a line-for-line analogue of externalImageOrigins() (:43-49), and the frame-src → child-src → default-src fallback at :134 is the CSP3 resolution order. index.html:5 (frame-src https://www.youtube-nocookie.com) and index.html:406 (the one <iframe>) satisfy both new rules. Ran node --test scripts/page-csp.test.mjs (34 pass) and scripts/coverage-floor.test.mjs (pass) at the PR head. Scope matches #310 exactly; no overlap with #309's files.

Low — path-form frame-src source expressions produce two misleading messages (scripts/page-csp.mjs:136,141). Browsers accept a path in a source expression (frame-src https://www.youtube-nocookie.com/embed/), but both new checks compare the raw token against new URL(src).origin, so that valid policy reports:

frame-src does not allow external <iframe> origin https://www.youtube-nocookie.com
frame-src allows https://www.youtube-nocookie.com/embed/ but no <iframe> on the page uses it

(reproduced with problemsOf() on a fixture). The first message is a pre-existing limitation shared with the img-src rule; the second is new and is the one that would send a contributor looking for a frame that is there. If you want to keep the origin-only policy as a repo convention, a one-line README note ("list origins, not paths") would make the failure self-explanatory; otherwise normalising the token with new URL(token).origin before comparing would accept path forms. Either is fine with me — the site's current policy is unaffected.

Evidence bundle `#3111524cb4` sha256:006dd716cd233a6efb2361e70ca5b2d9add9f61dfef23a8326560cc6484e881d — download from the dashboard or `hivectl review evidence #311`.

@hivecommons-hive
hivecommons-hive Bot merged commit 3e472ec into main Oct 31, 2026
6 of 7 checks passed
@kubestellar-prow
kubestellar-prow Bot deleted the quality/test-csp-frame-src branch October 31, 2026 13:28
@hivecommons-hive hivecommons-hive Bot removed role/trusted Author is trusted for unattended merge (trusted-author role or registry/claim tier in require_tiers) stage/050-review-pending Review swarm requested; awaiting a verdict for the current head labels Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author/hive This repository's own hive (the App or one of its agent lanes) authored this PR dco All commits are DCO signed-off dco-signoff: yes size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[quality] page-csp gate does not check iframe origins against frame-src

0 participants