Defaults.Exposed

Defaults.ExposedFixes › Clickjacking protection (X-Frame-Options)

How to fix Clickjacking protection (X-Frame-Options)

A one-line instruction that tells browsers not to let other websites secretly load your site inside their own. Without it, a scammer can hide your real, logged-in pages behind a fake page and trick your customers into clicking things they never meant to — approving a payment, changing a password, granting access.

Bottom line for your business: A fraudster can invisibly wrap your live website inside a fake one and steal money or account access from your logged-in customers — and to the customer it looks like your site did it. The fix is free and takes a developer about 15 minutes; leaving it off is a known gap that both criminals and cautious buyers can spot in seconds.

What this can cost you

Why it matters. This is a free, one-line setting that takes minutes to add, and it shuts down a whole class of trickery aimed at your logged-in customers. On our scoring it is a worth-real-points web-security check rated high severity, because a missing header leaves a known, easily-checked hole that criminals automate and buyers look for.

What this is, in plain words

When someone visits your website, their browser can also be told to load your site inside another website — like a small window embedded inside a bigger page. That sounds harmless, and sometimes it is. But it’s the mechanism behind an attack called clickjacking.

Here’s the trick. A scammer builds their own page and quietly loads your real website inside it — invisibly, made fully transparent. Then they lay their own content on top: a flashy button, a “Play video,” a “Claim your prize.” Your customer sees the attacker’s page and clicks what looks like a harmless button. But because your real site is sitting invisibly underneath their cursor, the click actually lands on your page — confirming a payment, changing a password, approving access, accepting a permission. The customer thinks they clicked one thing; they actually clicked another, on a site they trust.

Clickjacking protection is a short, invisible instruction your website sends to every visitor’s browser that says, in effect:

“Don’t let other websites load me inside them. If someone tries, refuse.”

Modern browsers obey this automatically. With it switched on, the trick simply doesn’t work — the embedded copy of your site refuses to load. Without it, your site is fair game to be used as the hidden layer in a scam, and the customer who gets caught will associate the whole thing with your brand, not the attacker’s.

What this can cost you

These are realistic, everyday scenarios. We never name a real business; these are illustrations of how the gap gets used.

  1. The invisible “confirm.” A customer is logged into your account portal in one tab. They land on a page (from an ad, an email, a search result) that promises something tempting and shows a big “Continue” button. Hidden underneath that button is your real “Confirm transfer” or “Change email” control, loaded from their own logged-in session. They click “Continue” — and unknowingly authorise a change on their actual account with you. To them, and to your support team, it looks like they did it on your site.

  2. The settings hijack. An attacker frames your account-settings page and overlays an innocent game or survey. A few clicks in the right places silently flip a setting — adding the attacker’s email as a recovery address, granting an app permission, or disabling a security alert. The account is now quietly compromised, and nothing looked wrong at the time.

  3. The deal that stalls. A larger customer sends their standard security questionnaire before signing. One line asks whether your site sets anti-framing protection (X-Frame-Options / CSP frame-ancestors). Your IT contact has to answer “no,” and procurement pauses while you scramble to fix a free, 15-minute setting that now looks like a red flag in front of a buyer.

  4. The brand-as-bait campaign. Because your real, trusted pages can be embedded, an attacker uses your login or checkout as the convincing layer in a wider phishing campaign. The customers who get caught don’t blame the shadowy attacker — they remember it as the time “your site” let them get scammed.

  5. The audit flag. An insurer’s scan, or an auditor reviewing your security posture, lists missing clickjacking protection among the findings. It’s a textbook basic-hygiene item; having it flagged signals that the easy, free protections weren’t in place — which colours how the rest of your security is judged.

The through-line: the damage lands on a real, logged-in customer doing something they didn’t intend — and it carries your name, not the attacker’s.

What it actually is

When a browser asks your website for a page, your server sends back the page plus some invisible “headers” — extra instructions the browser reads but the visitor never sees. Clickjacking protection is delivered through these headers. There are two, and our check passes if either is present:

1. The older header — X-Frame-Options:

X-Frame-Options: SAMEORIGIN

This is the long-standing, widely-supported control. It takes one of two practical values:

2. The modern header — Content-Security-Policy frame-ancestors:

Content-Security-Policy: frame-ancestors 'self';

This is the newer, more flexible control and the one current standards point to. It does the same job but lets you be precise about who may embed you:

What “good” looks like

The strongest setup uses both: frame-ancestors for modern browsers (and for the precision of naming allowed embedders) and X-Frame-Options: SAMEORIGIN as a fallback for older clients. Our check is satisfied by either one on its own — but since both are free and take the same few minutes, there’s no reason not to set both.

One important detail your developer should know: a Content-Security-Policy-Report-Only header does not enforce anything — it only reports. If you want clickjacking protection to actually take effect, it must come from an enforcing header (a normal Content-Security-Policy with frame-ancestors, or X-Frame-Options), not a report-only one.

How to fix it (free, ~15 minutes)

Hand this section to whoever runs your website — your IT person, web developer, or hosting support. The fix is free. It’s one or two response headers, or a rule in your CDN. There is nothing to buy.

The check passes when either an X-Frame-Options header (set to DENY or SAMEORIGIN) or a CSP frame-ancestors directive is present. The recommended belt-and-braces setup adds both.

Step 1 — Decide how strict to be

Step 2 — Add the headers (pick your platform)

Nginx — inside your server block:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header Content-Security-Policy "frame-ancestors 'self';" always;

Apache — ensure mod_headers is enabled, then in your virtual host:

Header always set X-Frame-Options "SAMEORIGIN"
Header always set Content-Security-Policy "frame-ancestors 'self';"

Microsoft IIS — in web.config inside <customHeaders>:

<add name="X-Frame-Options" value="SAMEORIGIN" />
<add name="Content-Security-Policy" value="frame-ancestors 'self';" />

Cloudflare (or a similar CDN): go to Rules → Transform Rules → Modify Response Header, and add two rules that set X-Frame-Options to SAMEORIGIN and Content-Security-Policy to frame-ancestors 'self'; on all responses. This is the easiest route if you don’t have direct server access.

Already sending a Content-Security-Policy for other reasons? Don’t create a second CSP header — add frame-ancestors into your existing policy. Two CSP headers can conflict.

Website builders (Squarespace, Wix, Shopify and similar): these platforms often set anti-framing protection for you, so you may already pass with nothing to do. If our check flags it, the control is usually in the platform’s security settings, or you add it at the CDN sitting in front of the site. (Note: Google Workspace and Microsoft 365 power your email, not your website — this header is set wherever your public site actually lives, not in Workspace/365 admin.)

Step 3 — Reload and verify

Reload the web server or deploy the CDN rule, then load your live site and check the response headers — browser dev tools → Network tab → click the page request → Response Headers, or any free header-checking tool. Confirm the header(s) appear on real page responses, not just the homepage. Then re-run the check.

Common mistakes

FAQ

I'm not technical — can I deal with this myself?

You don't need to do the technical part. It's a single setting added to your website's server or your CDN, and any web developer or IT provider can add it in a few minutes. Hand them the 'How to fix it' section below — it tells them exactly what to add. The fix is free; we only charge if you'd like us to keep monitoring that it stays in place.

Will this stop my own site, or legitimate partners, from displaying my pages?

Only if you set it too strictly. The common setting ('SAMEORIGIN', or 'frame-ancestors self') still lets your own website embed its own pages normally — it only blocks outside sites. If a genuine partner needs to embed one specific page of yours, your developer can allow that single source while still blocking everyone else.

We're a small business — would anyone really bother targeting us?

These attacks are run in bulk by automated tools, not hand-picked. Smaller sites are often hit precisely because they're the ones missing basic protections like this. The attacker doesn't need to know who you are — they just need your site to be embeddable. Closing the gap costs you nothing.

What does 'good' actually look like?

Either an X-Frame-Options header set to SAMEORIGIN (or DENY), or a Content-Security-Policy with a frame-ancestors directive — ideally both. Our check passes if either one is present. The modern, more flexible control is frame-ancestors; X-Frame-Options is the older header that still covers some legacy browsers, so the belt-and-braces setup uses both.

Isn't this the same as the SSL padlock or HTTPS?

No — they protect against completely different things. HTTPS encrypts the connection so nobody can read it in transit. Clickjacking protection stops your pages being loaded inside someone else's site at all. You can have a perfect padlock and still be wide open to clickjacking. They're separate checks and you want both.

If we don't fix it, does it lower our grade?

Yes. This is a scored web-security check, not informational — a missing header costs points and is rated high severity, because it directly exposes your logged-in customers to fraud. It's also one of the cheapest points to recover: a single free header, about 15 minutes of a developer's time.