How to block clickjacking?
clickjacking-no-frame-ancestorspage
Clickjacking occurs when a page is embedded in an iframe and positioned to trick users into clicking interface elements they cannot see. Without frame embedding restrictions, any site can load the page in a frame. The frame-ancestors CSP directive controls which origins can embed the page, preventing unauthorized framing.
What’s wrong
The page lacks frame embedding restrictions. Any site can load it in an iframe, overlay it with misleading interface elements, and manipulate click targets. A transparent iframe over a deceptive button causes users to click authenticated actions without awareness. The page has no control over its embedding context.
Why it matters
Clickjacking defeats user intent through interface deception. An authenticated user clicks what appears to be a game or innocuous button but actually triggers a fund transfer, permission grant, or account change. The legitimate page processes the authenticated action because the session is valid. The attack succeeds without compromising credentials. User action appears voluntary but context is manipulated.
The correct change
Add frame-ancestors directive to Content-Security-Policy header. Set it to ‘none’ to prevent all framing, or specify trusted origins that may embed the page. The end state is explicit control over embedding contexts. The page loads only when framing policy permits, preventing unauthorized interface manipulation through iframes.
Scope
This condition applies at the page level. Each response can set its own frame-ancestors policy. Global configuration typically applies the same policy across all pages. Pages requiring embedding can allow specific origins while sensitive pages prohibit all framing.
How to verify
- Validation confirms the condition is resolved:
- • Content-Security-Policy header includes frame-ancestors directive
- • Frame-ancestors set to ‘none’ or lists specific allowed origins
- • Browser blocks embedding attempts from unauthorized origins
- • Attempting to load page in iframe from disallowed origin fails
- • Console shows CSP violation when unauthorized framing is attempted
- • Pages requiring embedding still load in permitted contexts
- • Security scanners confirm clickjacking protection is active
Takeaway
- Clickjacking manipulates interface context to trick authenticated users
- Frame-ancestors CSP directive controls which origins can embed pages
- Setting frame-ancestors to ‘none’ prevents all iframe embedding
- The directive is more flexible and powerful than X-Frame-Options
FAQ
Should frame-ancestors be set to ‘none’ or ‘self’?
Use ‘none’ unless the page needs to embed itself. Same-origin framing is legitimate for some applications but unnecessary for most pages. Sensitive pages like login and account management should always use ‘none’. Content pages can use ‘self’ if legitimate same-origin embedding exists.
How does frame-ancestors differ from X-Frame-Options?
Frame-ancestors is part of CSP and supports multiple origins, more granular control, and better browser reporting. X-Frame-Options is simpler but less flexible. Use frame-ancestors in new implementations. Both headers can coexist for backward compatibility.
Can frame-ancestors break legitimate embedding?
Yes. If third parties legitimately embed content via iframe, they must be added to frame-ancestors. OAuth flows, payment widgets, and social sharing may require specific origins. Audit existing embedding relationships before deploying restrictive policies.
Does blocking iframes prevent all clickjacking?
It prevents iframe-based clickjacking, which is the most common form. Other techniques like popup window manipulation exist but are less reliable. Frame-ancestors eliminates the primary clickjacking vector for most sites.
What happens when frame-ancestors conflicts with X-Frame-Options?
Browsers prioritize frame-ancestors when both are present. If policies conflict, frame-ancestors takes precedence in supporting browsers. Set both headers consistently to avoid confusion and ensure backward compatibility.
Should content pages and functional pages use different policies?
Consider it. Marketing content might allow embedding for distribution. Account management and authenticated actions should prohibit framing entirely. Differentiate based on functionality and risk. Sensitive pages benefit from strictest policies.
The fix
Prevent clickjacking by controlling which origins can embed the page in frames
Done when: Content-Security-Policy includes frame-ancestors directive set to ‘none’ or specific allowed origins, preventing unauthorized iframe embedding
Do not
- Do not use frame-ancestors ‘self’ when no same-origin framing is needed
- Do not rely on JavaScript frame-busting as primary protection
- Do not assume clickjacking is low risk because authentication requires multiple steps
- Do not use wildcard origins in frame-ancestors for convenience
How to verify
- Content-Security-Policy includes frame-ancestors directive
- Browser blocks unauthorized framing attempts
- CSP violation logged when disallowed embedding is attempted
- Legitimate embedding contexts still work if permitted
- Security scanners confirm clickjacking protection
Find every page with this
probeo monitors this continuously across every page of your site, and records which pages passed, which failed, and which it could not determine.
Book a Call