All guides

CSP frame-ancestors

frame-ancestors is a Content-Security-Policy directive that lists the sites allowed to put your page in a frame. It works only as an HTTP header, not in a meta tag. When it is enforced, browsers ignore X-Frame-Options.

5 min read · Updated

Syntax

Content-Security-Policy: frame-ancestors <source> <source> ...
ValueWho can frame the page
'none'Nobody. Same as X-Frame-Options: DENY.
'self'Pages with the same origin.
https://partner.examplePages on that exact origin.
https://*.partner.examplePages on any subdomain of partner.example. The bare domain partner.example does not match.
https:Any site on HTTPS.
*Any site.

Put the single quotes around 'none' and 'self'. Without quotes, the browser reads self as a host name.

Common policies

Allow only your own site:

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

Allow your site and one partner:

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

Allow a partner and all its subdomains:

Content-Security-Policy: frame-ancestors https://partner.example https://*.partner.example

Block all frames:

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

If you already send a CSP, add frame-ancestors to it. Separate directives with a semicolon:

Content-Security-Policy: default-src 'self'; img-src 'self' data:; frame-ancestors 'self' https://partner.example

Rules that cause surprises

Every ancestor must match

The browser checks each frame above the page, up to the top window. If https://partner.example frames a page that frames yours, both origins must be in your list.

It does not fall back to default-src

default-src 'none' does not block framing. If a policy has no frame-ancestors, any site can frame the page, unless X-Frame-Options blocks it.

A meta tag does not work

<!-- frame-ancestors is ignored here -->
<meta http-equiv="Content-Security-Policy" content="frame-ancestors 'self'" />

Browsers ignore frame-ancestors in a <meta> tag. Send it as an HTTP response header.

Report-only does not block

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

This header only reports. The page still loads in any frame. It also does not switch off X-Frame-Options. Use it to test a new list before you enforce it.

Two policies: both must allow the frame

The app and the proxy can each send a Content-Security-Policy header. The browser enforces every policy. A frame loads only if all of them allow it. So frame-ancestors 'self' from the app still blocks the partner when the proxy adds a second policy that lists https://partner.example.

Edit the one policy that already exists. Do not add a second one.

Use origins, not paths

List the scheme and host, plus the port if it is not the default. Do not add a path like https://partner.example/app. The browser compares the origin of each ancestor, so a path can make the match fail.

How it works with X-Frame-Options

The HTML standard says browsers skip X-Frame-Options when an enforced CSP has frame-ancestors. So this response can be framed by the partner:

X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self' https://partner.example

Remove X-Frame-Options anyway when you allow other sites. It confuses people who read the headers, and some scanners still flag it. See X-Frame-Options.

The error you see when it blocks

Chrome shows "refused to connect" in the frame and prints this in the console:

Framing 'https://your-site.com/' violates the following Content Security Policy directive: "frame-ancestors 'self'". The request has been blocked.

Older Chrome versions print "Refused to frame ... because an ancestor violates the following Content Security Policy directive". Each browser words it in its own way. These pages show the exact text, the cause, and the fix:

To match any other frame error to its header, see Find the header that blocks your iframe.

Try your policy

After you deploy, paste the page URL into the iframe tester. It checks if the page can load in a frame, explains the result, and shows the fix.

To check many pages at once, use the bulk check. It shows X-Frame-Options and frame-ancestors for up to 100 URLs.

Sources

Check your page now

Know before you embed.

Free, no sign-up, nothing stored. Paste a URL and get a verdict, a live preview, and the fix.