Clickjacking attack : All about Clickjacking

The Clickjacking attack allows to perform an action on victim site on visitor’s behalf.Many sites were hacked this way, including Twitter and Facebook (both fixed).

Click jacking


The overall idea is simple.

  1. A visitor is lured to evil page. No matter how. “Click to get 1000000$” or whatever.
  2. The evil page puts a “get rich now” link with z-index=-1.
  3. The evil page includes a transparent iframe from the victim domain, say and positions it so that “I like it” button is right over the link.

Here’s how it looks (half-transparent iframe for demo purposes):

Here’s how it looks (half-transparent iframe for demo purposes):

iframe { /* iframe from */

top:0; left:0; filter:alpha(opacity=50); /* in real life opacity=0 */ opacity:0.5; }
Click on the link to get rich now:
You’ll be rich for the whole life!

A click on the link actually happens on the iframe. Bingo! If the visitor is logged into facebook (and most of time he is), then receives the click on behalf of the visitor.

On Twitter, it was the “Follow” button.

Same code, but transparent iframe (click to see the victim button pressed):

Actually, any single-click action is doable. All we need is to position the victim site iframe right. Most of time, the markup allows it.

Key events are much harder to hijack, because if the iframe is invisible, then the text in it’s input fields are invisible too. The visitor will start to type, but won’t see any text and won’t continue the action.

Defences and the ways to break through

The frame busting is a the good old framing protection technique. If you want to be sure that the document is not shown in iframe, you can add the following code to it:

// <![CDATA[
if(top != window) {
  top.location = window.location
// ]]>

So, in theory, if the current window is not the topmost, then top.location is changed, so it will be topmost.

But in real life, such protection is too weak. It can be challenged and beaten. There are many ways for it. Let’s review a few.

Blocking top navigation

It is possible to block the navigation caused by top.location assignment, in the onbeforeunload event.

The handler of this event returns a string which becomes a question to the user, asking him whether he wants to leave the page or not.

The outer window is located at the evil domain, so of course, the hacker may put any question there, and the user will believe and him stay. It’s always like that.

In the example below, there is a protected iframe with the code:

Changes top.location to 

  top.location = ''
<input type="button" value="test" onclick="alert('button works')">

Here, the evil page cancels top location change with a smart onbeforeunload (the user should press cancel):

// <iframe src="" style="height:80px">

The event is not supported in Opera (at least Opera ⇐11) and ignored in this case by Chrome/Safari.

So the protection still works in Firefox and IE.

Other ways to workaround frame busting

  • In IE8, there is a proprietary security=”restricted” feature which forbids JavaScript in the frame.For example,
  • In Chrome (recent Webkit), we can use HTML5 sandbox attribute to allow scripts and forms, but forbid top navigation (no allow-top-navigation):So, iframe will be able to use scripts, but it may not change top.location.
  • Firefox and older IE can activate designMode in parent page, this also prevents frame busting (thanks to clickjacking page for the idea).

There are other ways to evade the simple frame busting defence, not listed here. Browsers try to fix hacks, but new ways continue to emerge.

The reliable frame busting defence

The most reliable method is to suspend showing the document until the top == window check:

The code of the defending frame:

// <![CDATA[

  if (self == top) {
    var theBody = document.getElementsByTagName('body')[0] = "block"
  } else { 
    top.location = self.location 
// ]]>...

In the example above, we use document.getElementsByTagName('body') instead of document.body, because this way of getting BODY it works in all browsers when the document is not ready.

The only way to workaround it is HTML5 sandbox attribute which prevents top navigation. But newer browsers which support sandbox also provide another, even better way to protect from clickjacking (see below).


All modern browsers support the X-Frame-Options header.

The header allows or disallows rendering of the document when inside an iframe.

It may have two possible values:

The document will be rendered (shown) in an frame only if the frame and it’s parent have the same origin.
The document may not be rendered inside a frame.

Browsers ignore the header if speicified in the META tag. So the following META will be ignored:

<meta http-equiv="X-Frame-Options" content="deny">


Let’s use the clickjacking demo example from the beginning of the article, but now the server adds X-Frame-Options="sameorigin" header.

In the code below, the iframe is half-transparent. Run it and note that the browser doesn’t render the iframe.

Click on the link below
You’ll be rich for the whole life!


Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s