Clickjacking is the attack where a malicious site loads your page in a transparent iframe and tricks the victim into clicking buttons they believe belong to the attacker. Two mechanisms stop it — and one of them is being deprecated.
The two defenses
| Mechanism | How it works | Status |
|---|---|---|
| X-Frame-Options: DENY / SAMEORIGIN | Header: browser refuses to frame the page | Legacy, well supported |
| CSP frame-ancestors | CSP directive: frame-ancestors 'none' / 'self' / allowlist |
Modern, more flexible |
What gets it wrong
-
X-Frame-Options: ALLOWALL— explicitly allows framing; instant FAIL. - CSP with
frame-ancestors *— same as ALLOWALL. - Only XFO while adding third-party widgets that need framing (you'll be forced to loosen CSP or drop XFO — do the reverse: keep CSP strict and use allowlists).
- Nothing: no XFO + no frame-ancestors = unprotected.
The passive check
Send the request and look for both headers:
curl -sI https://your-site.com | grep -iE "x-frame-options|content-security-policy"
If you see neither (or ALLOWALL), your page is frameable. My CLI reconpp flags this automatically with a suggested fix:
pip install git+https://github.com/bryanrafaelbueno/reconpp
reconpp -u https://your-site.com -f md -o report.md
Output shape:
[WARN] headers | Clickjacking (X-Frame-Options / frame-ancestors)
Fix: Add 'X-Frame-Options: DENY' or CSP 'frame-ancestors 'none''.
Recommendation
- New systems: CSP only (
frame-ancestors 'none'), no XFO. - Legacy: keep XFO until the CSP is enforceable.
- Never ALLOWALL; never frame-ancestors * (even for "trusted" embedders, use the explicit allowlist).
- If your site is embedded intentially (payment widgets etc.), document it and keep the allowlist minimal.
More pass/fail/repair items in the full 70+ point checklist — free sample at the store:
- Store (Pix): https://bryanrafaelbueno.github.io/audit-br-store/
- Free sample PDF: https://bryanrafaelbueno.github.io/audit-br-store/sample.pdf
Top comments (0)