[quality] page-csp gate does not check iframe origins against frame-src #310
Description
Finding
scripts/page-csp.test.mjs keeps every external <img> origin covered by img-src (externalImageOrigins() → problemsOf() in scripts/page-csp.mjs), but it has no equivalent rule for <iframe>. #307 added the site's first third-party frame (https://www.youtube-nocookie.com on index.html) together with frame-src https://www.youtube-nocookie.com in the CSP meta, and the only thing pinning the two to each other is a page-specific regex in scripts/featured-video.test.mjs.
Consequences the shared gate currently misses:
- An
<iframe>added to any page (or the same page pointing at another origin) with no matchingframe-srcentry passes the suite and is silently blocked by the browser — the same failure mode theimg-srcrule exists to catch. - A
frame-srcorigin that no<iframe>uses (left behind after a frame is removed, or added speculatively) passes the suite, so the policy can drift away from least privilege with no signal — the same drift the stalesha256-hash rule catches forscript-src.
Verified at 325a85f: problemsOf() returns [] for a fixture page whose policy is default-src 'none' with no frame-src and whose body embeds a frame of https://example.org/; node --test scripts/page-csp.test.mjs passes 30/30 and nothing reports it.
Recommendation
Extend the gate in scripts/page-csp.mjs the way it already handles images:
-
add
externalFrameOrigins(html)— the<iframe>counterpart ofexternalImageOrigins, reading each frame'ssrc; -
in
problemsOf(), resolve the effective directive asframe-src→child-src→default-src(CSP3 fallback order) and reportframe-src does not allow external <iframe> origin Xunless the origin orhttps:is listed; -
report
frame-src allows X but no <iframe> uses itfor every https origin in an explicitframe-srcthat no frame on the page points at; -
fixture self-tests for each new branch so
scripts/coverage-floor.test.mjsstays green, and a line in the README gate description. -
externalFrameOrigins()+problemsOf()frame rules inscripts/page-csp.mjs -
fixture self-tests in
scripts/page-csp.test.mjs -
README description of the gate updated
Decision taken by hive: fall back frame-src → child-src → default-src (the browser's resolution order) and accept https: as a wildcard exactly as the img-src rule does, so the two rules stay symmetrical and no existing page changes.
Priority
- Impact: medium — a missing
frame-srcentry breaks the only embedded player on the home page with no test signal; a stale one widens the frame allowlist silently. - Effort: low — ~20 lines mirroring the existing
img-srcrule plus fixtures.
Filed by quality agent (ACMM L4/L6 — full mode)
🐝 Hive Agent: quality | Instance: hosted-available-oke-11-placeholder-r05x | SHA: 325a85f
— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
Activity