How to restrict frame-src in a Content Security Policy?
csp:missing-frame-src page
The issue
A policy that doesn’t restrict frames lets anything injected into the page embed any site in an <iframe>. An attacker who can add markup, through a compromised script or an unescaped field, can place a fake login form or payment page inside yours, under your address bar. Nothing changes for visitors until it’s used.
The cause is a policy written for scripts and styles that never covers frames. Without frame-src, a browser falls back to child-src, then default-src; when none of them is set, frames are unrestricted.
Scope
Each response’s Content-Security-Policy header is checked, including every policy when it carries several. frame-src controls what your page embeds. It’s a different directive from frame-ancestors, which controls who can embed your page; see clickjacking.
How to check you have it
- In probeo:
csp:missing-frame-srcwhen no policy setsframe-src,child-srcordefault-src, andcsp:frame-src-wildcardwhen every policy that does allows*,https:orhttp:. Both are graded minor. - By hand: run
curl -sI https://example.com/ | grep -i content-security-policyand look forframe-src, thenchild-src, thendefault-src, in that order. - With a tool: Google’s CSP Evaluator reads a pasted policy and flags broad sources.
The fix
Set frame-src to the origins your pages actually embed, or to 'none' if they embed nothing.
List each embed by its exact origin: a video player, a map, a payment form. A default-src 'self' covers frames too, but a frame-src of its own keeps the list of embeds readable and separate from the rest of the policy.
Content-Security-Policy: default-src 'self'; frame-src https://www.youtube-nocookie.com https://js.stripe.com; frame-ancestors 'self'Done when: every policy restricts frames to named origins or 'none', and the check above comes back clean.
Do not
- Do not use
*,https:orhttp:inframe-src. - Do not rely on
frame-ancestorsto restrict what your page embeds; it controls the opposite direction. - Do not add an embed’s origin without checking every page that loads it.
FAQ
What’s the difference between frame-src and frame-ancestors?
frame-src decides which sites your page may show in a frame. frame-ancestors decides which sites may show your page in a frame. A policy needs both to cover embedding in each direction.
Does default-src count?
Yes. Probeo, like the browser, treats child-src and then default-src as the frame restriction when frame-src isn’t set. A policy with default-src 'self' isn’t reported as missing frame-src.
Is https: really as broad as *?
For frames, nearly. It allows any site served over HTTPS, which is almost every site, so probeo reports it the same way.
Which product detects this
Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.