- Published on
Clickjacking Attacks and Prevention
- Authors
- Name
- Teo Selenius
- Follow @TeoSelenius
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.
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
.
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.
Of course, in a real attack, we wouldn't have any opacity so that the page would look like this:
The code of https://evil.example
could look (in a very simplified form) like this:
<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 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.
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 is the attacker page with a little bit of opacity to show how it works.
Here 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.
You can fork and play around with the demo here and the attack here.
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.
X-Frame-Options: DENY
Alternatively, you could only allow framing but only from your website.
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.
For details on X-Frame-Options
browser support see this page
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.
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:
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.
Content-Security-Policy: ...other options... frame-ancestors https://foo.example
Read more about CSP and frame-ancestors
here.
For up-to-date status of the browser support for frame-ancestors
, check this page.
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 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.
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.