Preventing Clickjacking with Framebusting


Nov 7, 2008

Clickjacking is a recently disclosed attack where users are fooled into unknowingly performing sensitive actions on external sites. It’s been demonstrated in several videos. Although it’s similar to cross-site request forgery, it can’t be prevented using a secret token – all form submissions and link clicks look valid because the user is interacting with the actual site.

Several proposed fixes are outlined nicely here. I’d like to focus on framebusting, which is the simplest solution.

Framebusting uses JavaScript to “bust” out of any top-level frame, usually:

if (top != self) top.location.href = location.href;

Attempts to load a page that has this code into a frame will result in the framed page “busting” out of the frame and taking over the full browser window. It works - but there are some problems.

  1. It’s opt-in. No one is protected by default.
  2. It doesn’t work for pages that need to be in frames legitimately.
  3. JavaScript needs to be enabled.
  4. It may cause a performance hit.
  5. It can be defeated in Internet Explorer (6 and up) using the security=restricted attribute.

This last issue is troubling - the browser with the largest market share has a non-standard “feature” that looks like a security flaw. But the security=restricted attribute was implemented for a valid security reason. According to the project manager for IE, it was meant to protect against malicious advertisements in frames which may attempt to forward the user to unintended sites through JavaScript. Whether or not the net security “profit” of the feature is positive or negative is subjective, but it certainly has pros and cons.

As a side note, some researchers have found ways to bypass the security=restricted attribute, but it requires control of the outer frame, which doesn’t prevent clickjacking.

One way to deal with the problem of clickjacking when your site is placed in a security=restricted frame is to hide all content and then display it with JavaScript, along these lines:

<head>

<script type=”text/javascript”>

document.getElementById(‘all’).style.display = ‘block’;

</script>

</head>

<body>

<div id=”all” style=”display:none;”>

[Site content goes here]

</div>

</body>

This works because pages in frames that are set with a security=restricted attribute are placed in a zone that doesn’t execute script, by default, and the controls that the attacker would need to get you to click on are hidden. Many sites use a similar approach to give a friendly error message to people who don’t use JavaScript.

Not a perfect solution, but it does make it more difficult for the attacker. Until we have a complete solution, it’s what I’ll recommend and include in the .NET ESAPI.