CentralCSP
PoliciesContent-Security-PolicyDirectives

frame-ancestors

The CSP frame-ancestors directive controls which origins may embed your page in a frame, the modern anti-clickjacking control.

Last update:

The frame-ancestors directive controls which origins are allowed to embed the current page inside a <frame>, <iframe>, <object>, or <embed>. It is the modern defense against clickjacking, where an attacker loads your page in a hidden frame on their own site and tricks a user into clicking something they cannot see.

Note that this directive is about who can frame you, the reverse of frame-src, which controls what your page is allowed to load into its own frames.

Prevent any site, including your own, from framing the page:

Content-Security-Policy: frame-ancestors 'none'

Fallback chain

frame-ancestors has no fallback. default-src does not cover it, so a page with no frame-ancestors can be framed by anyone.

Values

frame-ancestors takes a source list of origins. Nonces and hashes do not apply, they describe content, not an embedding origin.

ValueStatusDescription
'none'✅ GoodNo origin may embed the page, including the same origin.
'self'✅ GoodOnly the page's own origin may embed it.
Host or scheme source✅ GoodAllows the listed host source or scheme source to embed the page, for example a partner domain.

You can list several ancestors. When the embedding chain does not match, the browser refuses to render the page in the frame. Avoid a wildcard or a bare scheme like https:, which lets any site frame your page and reopens the clickjacking risk; list only the specific origins that have a real reason to embed you.

Relationship to X-Frame-Options

frame-ancestors is the successor to the legacy X-Frame-Options header, and it is more expressive. The mapping is direct:

X-Frame-Optionsframe-ancestors equivalent
DENYframe-ancestors 'none'
SAMEORIGINframe-ancestors 'self'
ALLOW-FROM uri (obsolete)frame-ancestors https://partner.example

Where a browser supports both, frame-ancestors takes precedence over X-Frame-Options. X-Frame-Options could never list more than one allowed origin and its ALLOW-FROM form was dropped, so frame-ancestors replaces it. You can still send X-Frame-Options alongside for very old clients, but frame-ancestors is the control that matters today. We cover when to retire the legacy header in clickjacking protection without a CSP header and in legacy security headers to retire.

Examples

Allow only same-origin framing:

Content-Security-Policy: frame-ancestors 'self'

Allow a specific partner to embed the page:

Content-Security-Policy: frame-ancestors 'self' https://partner.example.com

Security notes

frame-ancestors works only as an HTTP response header. A <meta http-equiv> CSP cannot carry it, the browser ignores it there. The same is true of sandbox and the reporting directives. Set frame-ancestors in your server or edge configuration, not in markup.

The directive blocks clickjacking. In a clickjacking attack the victim's browser loads your real, logged-in page in a transparent frame layered over attacker content, so a click the user thinks lands on the attacker's button actually lands on your page (confirming a transfer, changing a setting, granting a permission). By restricting who may frame the page, you stop the page from rendering inside an attacker's document at all, which removes the attack surface.

Known bypasses and risks

frame-ancestors only governs framing. It does nothing about other navigation or script behavior, so it is one control among several in a complete policy. It also relies on the response actually carrying the header on every framed document, a page served without it from some path or cache can still be framed, so apply it consistently across the site.

Setting frame-ancestors 'none' on a page that is supposed to be embedded (a widget, an OAuth consent screen, a documentation snippet) breaks that embedding. Decide per page whether it should ever be framed, and by whom, then set the directive to match. Run the policy through the CSP evaluator to confirm the value is what you intend.

Recommendation

Ship frame-ancestors 'none' on pages that are never meant to be embedded, or 'self' if you frame your own pages, per the OWASP CSP cheat sheet.

Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY

The OWASP HTTP Headers cheat sheet recommends sending X-Frame-Options: DENY alongside for old clients; frame-ancestors takes precedence wherever both are supported.

Reporting

When the directive blocks a framing attempt, the browser emits a csp-violation report naming frame-ancestors as the effective directive. Wire delivery with the report-to directive and the Reporting-Endpoints header.

Browser support

frame-ancestors is part of CSP Level 2 and Level 3 and is widely supported across current browsers. Where supported it supersedes X-Frame-Options.

FAQ

Should I use X-Frame-Options or frame-ancestors?

frame-ancestors is the modern, more expressive successor to X-Frame-Options, and it wins wherever both are supported. Send both: frame-ancestors as the control that matters today, and X-Frame-Options: DENY alongside for very old clients. See the full comparison in X-Frame-Options vs frame-ancestors.

Can I set frame-ancestors in a meta tag?

No. frame-ancestors works only as an HTTP response header. A <meta http-equiv> CSP cannot carry it, and the browser ignores it there, the same as the sandbox and reporting directives. Set it in your server or edge configuration on every framed document, not in the page markup.

frame-ancestors 'none' or 'self'?

'none' blocks all framing, including same-origin, so use it on pages that are never meant to be embedded. 'self' allows only the page's own origin to frame it, so use it when you embed your own pages. Any other origin listed must have a real reason to embed you.

See also

Sources

On this page