Clickjacking Attacks and Prevention
Tags: webdev, security, cybersecurity, programming
Published: 2021-04-01 09:16:56

In this article, you will learn about clickjacking attacks, how they work, how they can put your website users at risk, and how you can prevent it. You can read the original article [here](https://www.appsecmonkey.com/blog/clickjacking)

## What is Clickjacking?

Clickjacking attacks trick a website user to perform unwanted actions on a website unwittingly. It works by layering the target website in an invisible frame on a malicious website. When the user thinks they are clicking a button on the attacker's page, in reality, they click something on a completely different website.

## An example

Let's say we have a firewall administrator who is logged in at `https://firewall.example`.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3ft4amml1btjpzm86wy.png)

What an attacker could do, is create a page like this. It tricks the user into clicking a button. In reality, the user would be disabling the firewall because the firewall management page is layered on top of the button in an iframe.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wbcxi110ynyvnby0s2p.png)

Of course, in a real attack, we wouldn't have any opacity so that the page would look like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/br1id0o658jsv3pv8x7w.png)

The code of `https://evil.example` could look (in a very simplified form) like this:

```html
<div class="underlay">
  <h1>WANT A MILLION DOLLARS?</h1>
  <button>CLICK ME</button>
</div>
<iframe class="invisible-overlay" src="https://firewall.example"></iframe>
```

## A live demo

[Here](https://tw1go.sse.codesandbox.io/) is a little web application. You can try it out right now. Click the button to enable and disable the firewall, but leave it turned on so that we can turn it back off with a clickjacking attack in a minute.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g9qdbz1eeothwzxoyq30.png)

The attacker will create a page that shows a button "CLICK ME" and then overlays the target application on top of the button. Instead of clicking the "CLICK ME" button, the user will unwittingly click the "DISABLE" button on the firewall management page.

[Here](https://lbgq0.csb.app/) is the attacker page with a little bit of opacity to show how it works.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8sxva40pr5wvml59lgrb.png)

[Here](https://wjunr.csb.app/) is the final attack, where the frame is entirely invisible. Try to click the button and then scroll back up to the firewall page. Observe how the firewall has been disabled.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2agbh4l6x8wsaxbzxwbo.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cgc5kscur6dfyj4nle0m.png)

You can fork and play around with the demo [here](https://codesandbox.io/s/clickjacking-demo-tw1go?file=/public/index.html) and the attack [here](https://codesandbox.io/s/clickjacking-demo-opacity-lbgq0).

## Preventing clickjacking attacks

The only way to prevent clickjacking attacks is to block other websites from framing your website. There are a couple of ways to do this.

### X-Frame-Options header

You can use the `X-Frame-Options` HTTP response header to tell browsers not to frame your website at all.

```yaml
X-Frame-Options: DENY
```

Alternatively, you could only allow framing but only from your website.

```yaml
X-Frame-Options: SAMEORIGIN
```

However, `X-Frame-Options` cannot be used to allow specific websites to frame your website and is being obsoleted by `Content-Security-Policy`. Read more [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options).

For details on `X-Frame-Options` browser support see [this page](https://appsecmonkey.com/browser-support/x-frame-options)

### Content-Security-Policy

The `Content-Security-Policy` HTTP response header has a directive called `frame-ancestors` which you can use to prevent the framing of your website.

```yaml
Content-Security-Policy: ...other options... frame-ancestors 'none'
```

Or, just like with `X-Frame-Options` you could allow your website to frame itself like so:

```yaml
Content-Security-Policy: ...other options... frame-ancestors 'self'
```

The main benefit of using CSP instead of `X-Frame-Options` is that you can also allow specific external websites to frame your website.

```yaml
Content-Security-Policy: ...other options... frame-ancestors https://foo.example
```

Read more about CSP and `frame-ancestors` [here](https://appsecmonkey.com/blog/csp#frame-ancestors).

For up-to-date status of the browser support for `frame-ancestors`, check [this page](https://appsecmonkey.com/browser-support/content-security-policy#frame-ancestors).

### Isolation Policy

The third way to prevent framing is to implement an isolation policy with fetch metadata headers. However, fetch metadata is not yet supported by all browsers. As such, you must also implement either `X-Frame-Options` or `Content-Security-Policy` with `frame-ancestors`.

To implement an isolation policy that prevents framing:

- Create a middleware class that filters HTTP requests based on their headers.
- Based on the fetch metadata request headers, block requests that come from other websites.
- If you also want to block your website from framing itself, also block all navigation requests that are not destined to a document.

I understand this sounds a little bit abstract if you aren't familiar with fetch metadata headers. [Here](https://appsecmonkey.com/blog/fetch-metadata) is an entire article about the topic with a complete example that you can run on CodeSandbox.

For up-to-date status of the browser support for fetch metadata headers, check [this page](https://appsecmonkey.com/browser-support/fetch-metadata).

## Summary

Clickjacking attacks are a real threat to web applications. The only way to prevent them is not to allow other websites to frame your web application.

Luckily browsers enable us to do this. The most important defense is to deploy an `X-Frame-Options` or a `Content-Security-Policy` header that blocks framing.

You can achieve a nice additional defense layer by blocking requests to frames on the server-side by implementing an isolation policy with fetch metadata headers.

## Get the web security checklist spreadsheet!
[![Subscribe](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3iqd1ef4a5a0icyvvk65.jpg)](https://eepurl.com/hqAGt5)
 ☝️ [Subscribe](https://eepurl.com/hqAGt5) to AppSec Monkey's email list, get our best content delivered straight to your inbox, and <b>get our 2021 Web Application Security Checklist Spreadsheet for FREE</b> as a welcome gift!

## Don't stop here
If you like this article, check out the other application security guides we have on [AppSec Monkey](https://www.appsecmonkey.com/) as well.

Thanks for reading.