When I first heard about clickjacking, I was amazed at how easy it is to use this type of attack and what damage it can do. Later I was amazed at how easy it is to secure your site against clickjacking. Now I’m just amazed at how many websites are still vulnerable. I’ve been thinking about it for some time and the only reason I can come up with is a lack of awareness, so here’s my contribution to making this world a little better (safer).
First some background: In a clickjacking attack, a hacker attempts to ‘hijack’ clicks and send them to a different component then where the user expects them to go, causing all kind of actions on behalf of the unknowing user. This may be sending emails, creating users, transferring money, allowing unrestricted access to your webcam… or worse. Basically any action can be executed unknowlingly if a site is not properly protected. While clickjacking attempts to hijack clicks, it is also possible to hijack other mouse events, or key strokes. This is all part of something we call “window UI redress”. In a redress attack, a hacker will ‘redress’ a site, so it looks different from what the user is accustomed to. The user won’t probably even know that he has loaded that site. Usually the hacker does this by loading the site in an iframe and making that iframe completely invisible, while showing something different behind it. It is also possible to show something on top of the site, and passing all events on to the element behind it (in this case an element inside the iframe).
Let’s illustrate this with a simple example page a hacker can make:
The vulnerable site is loaded in an iframe, with opacity set to 0, making it invisible. It is positioned in such a way, that the location where the hacker wants a user to click is right behind some shiny button.
A nice real-world example that I like, is the clickjacking vulnerability in the Adobe Flash settings page in 2011 that allowed a hacker to view webcams from any user around the world without their knowledge: https://youtu.be/K8yrSUGa4go. Feross Aboukhadijeh explains how he found the bug and created a simple game to demonstrate it. This also shows that clickjacking does not just have to be about a single click, but can also mean complex patterns of clicks or other interactions.
So, how do you prevent all this? The basic idea is to control whether your site can be loaded in an <iframe> (or <frame>, <object>, <embed> or <applet>) or not, and if it’s allowed, on what domains then.
Never load in an iframe
First the HTTP headers. Add these to any response to the browser. Oh, and don’t forget that your mobile site needs them too! And also remember any .swf files you’re using, or other objects that can be included through their own request URL.
The first header is old and not very flexible, but it’s the only thing that works in most versions of Internet Explorer and some other browsers. The second header is newer and therefore unfortunately not yet (fully) supported in all browsers. So you will want to use both headers.
Second, you should also add a frame-busting script that checks if your site is the top-level domain and redirects the user to safety if it isn’t.
If you put the above styling and script in the head-section of your page, you should be safe. Well, … as safe as can be expected on the Internet. And again, don’t forget to include the script also in your mobile site.
only load in iframes on a specific domain
If your site needs to run in an iframe on a specific domain, simply specify the domain:
Note that in the X-Frame-Options header you need to be more explicit and also specify the protocol.
ONLY LOAD IN IFRAMES ON A multiple SPECIFIC DOMAINs
What if your site needs to run on multiple domains? Unfortunately the X-Frame-Options headers is not so flexible, so you just can’t specify this. A possibility might be to detect which parent domain is used (e.g. through an explicit referrer parameter) and set the X-Frame-Options accordingly if allowed. Otherwise, you need to rely on Content-Security-Policy. In practice, that would mean that Internet Explorer (at least until IE11) won’t be able to give your users any safety regarding clickjacking. You can find out which browsers support Content-Security-Policy on http://caniuse.com/#feat=contentsecuritypolicy.
Just for the sake of compleness, I should mention that there are also ways users can protect themselves from the browser side through all kinds of browser plugins, but that’s a whole different story. Perhaps a topic for a new blogpost?