1. Abstract
Prevent unwanted framing with an enforcing CSP frame-ancestors directive or a valid X-Frame-Options fallback.
Frame protection blocks hostile sites from embedding pages in deceptive frames, reducing clickjacking and UI redressing risk.
2. Classification
- Check ID
- frame-protection
- Check version
- 1.0.0
- Package path
- lib/checks/frame-protection/versions/1.0.0
- Category
- Security & Trust
- Subcategory
- Security & Trust
- Check group
- Browser Trust
- Check group ID
- browser-trust
- Maturity
- Established
- Scope
- page
- Check weight
- 1
3. Input And Output Contracts
- Input
- [email protected]
- Output
- [email protected]
- Resources inspected
- Content-Security-Policy frame-ancestors, X-Frame-Options, Clickjacking defense
4. Scoring Semantics
| Step ID | Title | Weight | Description |
|---|---|---|---|
applicability | Validate response applicability | 0.15 | Classify whether the scanned response is a browser-rendered document where frame protection is expected. |
csp-frame-ancestors | Validate CSP frame-ancestors | 0.35 | Parse enforcing, report-only, and meta CSP and evaluate the effective frame-ancestors directive. |
x-frame-options | Validate X-Frame-Options | 0.25 | Parse DENY, SAMEORIGIN, obsolete ALLOW-FROM, invalid values, and duplicate effective values. |
conflict-review | Review CSP and XFO interaction | 0.1 | Detect modern-browser CSP behavior and legacy-browser X-Frame-Options conflicts. |
observed-responses | Review observed browser responses | 0.15 | When Chrome response evidence is available, check sampled same-origin HTML document responses for frame protection. |
5. Package Documentation
Frame Protection Check v1.0.0
Status
- Version:
1.0.0 - Check identifier:
frame-protection - Input contract:
[email protected] - Output contract:
[email protected] - Scope: page
Abstract
This check validates whether a browser-rendered HTML document limits who may embed it in a frame. It treats an enforcing Content-Security-Policy frame-ancestors directive as the modern full-pass control and treats X-Frame-Options: DENY or SAMEORIGIN as a legacy baseline that returns warning when no enforcing frame-ancestors directive is present. When browser-observed response evidence is available, it also reviews sampled same-origin HTML document responses for equivalent protection.
Motivation
Clickjacking and UI redressing attacks embed a target page in a hostile frame and trick a user into interacting with it. Frame protection matters most for sign-in, account, checkout, payment, admin, authorization, settings, form, and authenticated-data pages.
Normative Model
Content-Security-Policy: frame-ancestors ... is the modern browser control for restricting which ancestors may embed a protected resource using frame, iframe, object, or embed.
Important CSP behavior:
frame-ancestors 'none'blocks all embedding.frame-ancestors 'self'allows same-origin embedding.- explicit scheme and host sources can allow selected embedding partners.
- every ancestor in the embedding chain must match the source list.
frame-ancestorsdoes not fall back todefault-src.frame-ancestorsmust be delivered in an enforcing CSP response header.frame-ancestorsin a meta CSP is ignored.frame-ancestorsinContent-Security-Policy-Report-Onlyreports but does not block.- if an enforcing CSP policy contains
frame-ancestors, modern browser processing uses that policy instead ofX-Frame-Options.
X-Frame-Options is a legacy control. DENY and SAMEORIGIN are valid baseline values. ALLOW-FROM is obsolete in modern browsers and does not satisfy this check.
Applicability
The check applies to the scanned page response and expects a browser-rendered HTML document, especially pages with sensitive or meaningful user interaction.
Redirects, no-body responses, non-HTML assets, JSON API responses, binary downloads, fonts, images, CSS, JavaScript, and plain text responses fail this check when scanned as the primary page response.
Pages intentionally designed for third-party embedding should use a narrow explicit frame-ancestors allowlist. They are not required to use DENY or 'none'.
Pass Criteria
An applicable HTML response fully passes when it has one of:
- enforcing CSP with parseable
frame-ancestors 'none' - enforcing CSP with parseable
frame-ancestors 'self' - enforcing CSP with a narrow explicit list of trusted origins
X-Frame-Options: DENY or X-Frame-Options: SAMEORIGIN satisfies the legacy baseline but returns warning when no enforcing CSP frame-ancestors directive is present.
The strongest posture is an enforcing frame-ancestors directive, optionally paired with a compatible XFO fallback for older browsers.
Warning Criteria
Warnings include:
- protection relies only on
X-Frame-Optionswith no enforcingframe-ancestors - CSP
frame-ancestorsand XFO express different policies - enforcing
frame-ancestorsallows broad sources such ashttps: - XFO is invalid, obsolete, or conflicting while enforcing
frame-ancestorsstill protects modern browsers - Chrome-observed same-origin HTML documents have missing, invalid, or broad frame protection
- the response body is renderable but not clearly an HTML document
Failure Criteria
Failures include:
- scanned response is not a browser-rendered HTML document
- applicable HTML response has neither enforcing
frame-ancestorsnor valid XFO frame-ancestorsis malformed or emptyframe-ancestors 'none'is combined with other sourcesframe-ancestorsappears only in report-only CSPframe-ancestorsappears only in meta CSP- XFO is the only protection and uses
ALLOW-FROM - XFO is the only protection and is invalid
- XFO contains multiple conflicting effective values
- enforcing
frame-ancestorsuses*, effectively allowing arbitrary embedding
Evidence Model
The check emits step-level evidence for:
- final URL, status, content type, HTML likelihood, and applicability
- enforcing CSP presence and policy count
- report-only CSP presence and policy count
- meta CSP
frame-ancestorspresence - parsed
frame-ancestorsvalues, mode, validity, broad sources, and explicit origins - XFO presence, values, normalized values, parsed directive, obsolete
ALLOW-FROM, and duplicate/conflicting values - CSP/XFO interaction and which mechanism controls modern browser behavior
- sampled same-origin Chrome-observed HTML document responses, when available
Evidence must not include cookies, authorization headers, credentials, complete HTML, full response header dumps, or unrelated sensitive values.
Validation And Scoring Steps
applicability(0.15): classify whether the scanned response is a browser-rendered HTML document.csp-frame-ancestors(0.35): parse enforcing, report-only, and meta CSP and evaluateframe-ancestors.x-frame-options(0.25): parse XFO values, duplicate values, obsoleteALLOW-FROM, and legacy fallback quality.conflict-review(0.10): compare modern CSP behavior with legacy XFO behavior.observed-responses(0.15): when Chrome evidence exists, review sampled same-origin HTML document responses.
Standard Behavior
If an applicable page has restrictive enforcing frame-ancestors, it passes.
If an applicable page lacks frame-ancestors but has X-Frame-Options: DENY or SAMEORIGIN, it passes the legacy baseline with a warning that CSP frame-ancestors is preferred.
If frame-ancestors appears only in report-only or meta CSP, it does not count as protection.
If no valid frame protection is present on an applicable HTML page, the check fails.
Non-Standard And Real-World Behavior
Many security scanners accept either XFO or CSP frame-ancestors. This check distinguishes modern protection from legacy fallback because CSP supports multiple trusted embedding origins and is the browser-preferred control when both mechanisms are present.
JavaScript frame-busting and SameSite cookies can reduce clickjacking impact in some situations, but neither replaces browser frame blocking for this check.
Non-Goals And Limitations
This check does not:
- prove immunity to all clickjacking or UI redressing attacks
- execute interactive attack simulations
- inspect authenticated routes unless they are part of the scan
- prove every route has frame protection without route sampling
- require
DENYfor intentionally embeddable pages - treat JavaScript frame-busting as sufficient protection
- treat SameSite cookies as equivalent to frame protection
- treat
default-src,frame-src, orchild-srcas protection for the current page being embedded - treat report-only or meta
frame-ancestorsas enforced protection
References
- www.w3.org/TR/CSP3/#directive-frame-ancestors
- html.spec.whatwg.org/multipage/browsing-the-web.html#the-x-frame-options-header
- www.rfc-editor.org/rfc/rfc7034
- developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options
- developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/frame-ancestors
- cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
Source: lib/checks/frame-protection/versions/1.0.0/docs.md
6. Version Changelog
frame-protection v1.0.0 Changelog
Initial release.
- Evaluates enforcing CSP
frame-ancestorsfor modern frame protection. - Accepts
X-Frame-Options: DENYandSAMEORIGINas legacy baseline protection. - Rejects report-only or meta-delivered
frame-ancestorsas unenforced. - Rejects obsolete
X-Frame-Options: ALLOW-FROMas baseline protection. - Reviews sampled same-origin HTML document responses when browser response evidence is available.
Source: lib/checks/frame-protection/versions/1.0.0/changelog.md