From grimoire
Prevent clickjacking by setting X-Frame-Options and CSP frame-ancestors headers to block your pages from being embedded in attacker-controlled iframes.
How this skill is triggered — by the user, by Claude, or both
Slash command
/grimoire:prevent-clickjackingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Block your pages from being embedded in attacker-controlled iframes using `X-Frame-Options` and CSP `frame-ancestors` — eliminating UI redress attacks where invisible overlays trick users into unintended clicks.
Block your pages from being embedded in attacker-controlled iframes using X-Frame-Options and CSP frame-ancestors — eliminating UI redress attacks where invisible overlays trick users into unintended clicks.
Adopted by: Recommended by OWASP Top 10 2021 A05 (Security Misconfiguration) and NIST SP 800-53 SC-18. Twitter fell victim to a major clickjacking attack ("likejacking") in 2009 before deploying frame-busting. Facebook, Google, and GitHub all deploy X-Frame-Options: DENY or equivalent CSP. Mozilla Observatory and securityheaders.com penalize missing frame protection.
Impact: Clickjacking enables attacks ranging from social engineering (forced likes, follows) to high-impact account compromise (changing email/password via one-click on a framed settings page). The 2010 "Filejacking" attack used clickjacking to steal Adobe Flash local storage via framed permissions dialogs. Proper frame protection eliminates the entire attack class at zero performance cost.
Why best: JavaScript frame-busting code (checking window.top !== window.self) is the legacy alternative — it's defeated by the sandbox="allow-scripts allow-same-origin" iframe attribute, introduced in HTML5. Header-based protection (X-Frame-Options, frame-ancestors) operates at the browser level and cannot be bypassed by iframe sandbox attributes.
Sources: OWASP Clickjacking Defense Cheat Sheet; Marcus Niemietz (Ruhr-Universität Bochum) — "Clickjacking Revisited" (2012); CWE-1021
Set X-Frame-Options header — works in all browsers including IE:
X-Frame-Options: DENY
Use SAMEORIGIN only if your app legitimately embeds its own pages in iframes (e.g., an internal dashboard embedding sub-pages):
X-Frame-Options: SAMEORIGIN
Never use ALLOW-FROM — it is not supported in Chrome/Firefox and is silently ignored.
Set CSP frame-ancestors (preferred, supersedes X-Frame-Options):
Content-Security-Policy: frame-ancestors 'none'
frame-ancestors 'none' is equivalent to X-Frame-Options: DENY.
frame-ancestors 'self' is equivalent to X-Frame-Options: SAMEORIGIN.
For specific trusted origins:
Content-Security-Policy: frame-ancestors 'self' https://trusted-parent.example.com
Set both headers for maximum browser coverage — X-Frame-Options covers older browsers; frame-ancestors covers modern ones and takes precedence when both are present:
add_header X-Frame-Options "DENY" always;
add_header Content-Security-Policy "frame-ancestors 'none'" always;
Apply to all HTML responses — not just login pages. Clickjacking targets any page with interactive elements. Configure at the server/framework level, not per-route:
Express:
const helmet = require('helmet');
app.use(helmet.frameguard({ action: 'deny' }));
Django:
# settings.py
MIDDLEWARE = ['django.middleware.clickjacking.XFrameOptionsMiddleware']
X_FRAME_OPTIONS = 'DENY'
Spring Security:
http.headers().frameOptions().deny();
If you must allow framing (widgets, embeds) — use frame-ancestors with an explicit allowlist and validate on the server that the embedding origin is trusted. Never use X-Frame-Options: ALLOW-FROM (unsupported in modern browsers):
Content-Security-Policy: frame-ancestors 'self' https://partner.example.com
sandbox and creates false confidence.X-Frame-Options: ALLOW-FROM is not supported in Chrome or Firefox — use CSP frame-ancestors with specific origins instead.frame-ancestors directive in CSP overrides X-Frame-Options in modern browsers — set both for full coverage.if (top !== self) top.location = self.location is bypassed by <iframe sandbox="allow-scripts allow-same-origin">.SAMEORIGIN when DENY would work — if no legitimate use case for framing exists, DENY is stricter and correct.npx claudepluginhub jeffreytse/grimoire --plugin grimoireTests web applications for clickjacking vulnerabilities by assessing frame embedding controls (X-Frame-Options, CSP frame-ancestors) and crafting proof-of-concept overlay attacks during authorized security assessments.
Tests web applications for clickjacking vulnerabilities by assessing frame embedding controls (X-Frame-Options, CSP frame-ancestors) and crafting proof-of-concept overlay attacks during authorized security assessments.
Tests web apps for clickjacking vulnerabilities by checking X-Frame-Options and CSP frame-ancestors headers with curl/bash, and crafting iframe overlay PoCs during authorized pentests.