Headers

What is Clickjacking? How X-Frame-Options Stops It

Clickjacking embeds your site in a transparent iframe on an attacker's page. The user thinks they are clicking the attacker's button — but they are clicking on your page behind it. One header line prevents this.

How a clickjacking attack works

The attacker creates a page with an iframe containing your site, positioned with CSS opacity: 0 over a visible button on their page. Your bank transfer confirmation page sits invisible underneath "Click here to win a prize." The user clicks the prize button — they are actually confirming a transfer on your bank's site, logged in as themselves.

<!-- Attacker's page -->
<div style="position: relative;">
  <iframe src="https://bank.example.com/transfer?amount=1000&to=attacker"
    style="opacity: 0; position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
  </iframe>
  <button style="position: relative; z-index: -1;">Click here to win!</button>
</div>

The fix — X-Frame-Options

Tell browsers not to allow your page to be embedded in iframes:

X-Frame-Options: SAMEORIGIN

With this header, browsers refuse to render your page inside an iframe on any other domain. The attack is impossible because the iframe will not load.

SAMEORIGIN vs DENY

The modern approach — CSP frame-ancestors

CSP frame-ancestors is more powerful: it supports multiple origins, regex patterns, and takes precedence over X-Frame-Options in modern browsers. Use both:

X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self';

Older browsers use X-Frame-Options. Browsers supporting CSP use frame-ancestors and ignore X-Frame-Options.

Check for X-Frame-Options → HeadersFixer