Clickjacking Defense in IE8

Bryan here. The Internet Explorer team released the first public release candidate build of IE8 last week, which includes some very handy new security features I’d like to talk about. Steve and I have both blogged about the IE8 Cross-Site Scripting (XSS) Filter when it came out in the last public beta, and I wrote a piece on my own blog praising IE’s XDomainRequest (XDR) mechanism for making more secure cross-domain requests. This post will complete the IE8 security feature blog post hat trick and give some background and usage guidance around the new X-FRAME-OPTIONS clickjacking defense header.

In case you’re unfamiliar with clickjacking, let me start from the top. All modern browsers support the iframe (inline-frame) HTML tag used to include content from another page in the current page. When the browser renders this tag, it fetches the page specified by the src attribute of the iframe tag and displays that page inside a region of the current page. For example:

<iframe src="http://www.microsoft.com/" height="200px" width="200px" />

Including this HTML tag on a web page will draw a 200×200 pixel frame displaying the home page of the Microsoft.com web site on that page. Users can interact with this frame just as if they had typed www.microsoft.com into the browser themselves; they can navigate hyperlinks, press buttons, submit forms, anything.

Last year, security researchers Jeremiah Grossman and Robert “RSnake” Hansen demonstrated an attack they called “clickjacking”. The attack works like this: the attacker first creates an HTML page that included an iframe sourced to a legitimate site, but he doesn’t just display the top left 200×200 pixels. Instead, he positions and sizes the iframe and other page elements so that only the pixels of a specific control, such as a button, of the victim page are visible. The attacker then presents this partial iframe control in a completely different context from its original context in order to trick users into pressing it. An example will help to explain this better.

The Contoso Bookstore web site has an excellent selection of computer security books and allows users to buy them with a single button click.

contoso_bookstore_1

An attacker now sets up a phony disaster relief web site with an iframe sourced to the Contoso site. He sets the iframe z-index to place it in the “back” of the page, then puts other page elements “over top” of it to cover the original text.

<iframe

src="http://www.contoso.com/bookstore/ajaxsecurity/"

AllowTransparency="yes"

style="float; position:absolute; left:0px; top:-200px; width: 300px; height: 275px; z-index: 5;"

border="0"

frameborder="0"

scrolling="no" />

<div style="position:absolute; left:0px; top:0px; width: 250px; height: 200px; background:white; z-index:10">

<h1>Please help</h1>

</div>

disaster_relief_1

Visitors to the site believe they’re donating to a disaster relief fund, but when they press the button, they’re really pressing the button on the Contoso web site, cleverly matted so that the users have no idea they’re pressing a button displayed in an iframe and not on the main document.

IE8 mitigates this vulnerability by allowing developers to specify that their content should not be displayed in iframes. Developers can add the HTTP response header X-FRAME-OPTIONS: DENY to a web page to specify that that page should never be displayed in a frame. Alternatively, developers can add the header X-FRAME-OPTIONS: SAMEORIGIN to allow that page to only be displayed in iframes when the main document’s domain matches that page’s domain. So www.contoso.com/bookstore could display an iframe of www.contoso.com/checkout, but evilsite.com could not display that frame.

(If you’d like more technical details on the X-FRAME-OPTIONS header, be sure to check out Eric Lawrence’s ClickJacking Defenses post on the IE blog.)

Adding the header to your page, at least in ASP.NET, is trivial:

this.Response.Headers["X-FRAME-OPTIONS"] = "DENY";

The question is, When should you add it? In many ways, clickjacking is very similar to cross-site request forgery (XSRF). Both are types of “confused deputy” vulnerabilities in which the server accepts and processes a request because it believes that the user intended to make that request. In an XSRF attack, the fraudulent request comes from malicious HTML or script, while in a clickjacking attack the fraudulent request comes from the user interacting with misleadingly labeled controls, but the effect is the same. Since these vulnerabilities are similar, we can make a generalization and say that the types of pages that require XSRF defense are the same types of pages that require clickjacking defense.

The value of both XSRF and clickjacking attacks is that the attacker can get the victim to perform an action with the victim’s credentials (usually stored in a cookie). In our earlier example, if the victim hadn’t been logged into the Contoso Bookstore then the attack would not have succeeded since there would be no account to charge the book purchase to. The key takeaway from this is that there’s really no reason to protect anonymously available pages from clickjacking. If the user doesn’t have to log into the site, there’s no need to apply the X-FRAME-OPTIONS header.

Furthermore, since clickjacking attacks rely on user interface elements, there’s no need to apply the X-FRAME-OPTIONS header to web service methods. No UI, no clickjacking.

Alternatively, you could avoid worrying about which pages to protect and which to skip and just apply the header for every page in the application. Just add an Application_BeginRequest method to the global.asax file and apply the response header in that method:

void Application_BeginRequest(object sender, EventArgs e)

{

  this.Response.Headers["X-FRAME-OPTIONS"] = "DENY";

}

Even better, you could apply the header automatically using the HTTP Response Header configuration feature in IIS 7 – no code changes required. You can set custom headers per-application or per-server to help protect all your sites.

Finally, if you need more functionality than the IIS custom header feature provides – such as not adding an X-FRAME-OPTIONS header if one already exists – you could create an HttpModule and then use IIS to apply that module to your applications.

public class XFrameOptionsModule : IHttpModule

{

#region IHttpModule Members

 

  public void Dispose()

  {

  }

  public void Init(HttpApplication context)

  {

  context.PreSendRequestHeaders += new

    EventHandler(context_PreSendRequestHeaders);

  }

 

#endregion

 

  void context_PreSendRequestHeaders(object sender, EventArgs e)

  {

    HttpApplication application = sender as HttpApplication;

    if (application == null)

      return;

    if (application.Response.Headers["X-FRAME-OPTIONS"] != null)

      return;

    application.Response.Headers.Add("X-FRAME-OPTIONS", "DENY");

  }

}

 

You can compile this code into a DLL and deploy it into the bin directories of any applications you want to protect. Then use IIS to apply the module to those web sites. You can find step-by-step instructions on how to accomplish this here – don’t worry, it’s extremely straightforward.

I highly recommend that you apply the X-FRAME-OPTIONS header to all web pages that you develop that you do not intend to be framed, whether by changing the application code directly, by configuring response headers in IIS, or by deploying an HttpModule. Clickjacking may not yet appear on anyone’s Top 10 Vulnerabilities List, but let’s nip it in the bud now and make sure it never gets there.

Join the conversation

2 comments
  1. jeff.williams@owasp.org

    For JavaEE developers, there’s an article on implementing this type of clickjacking protection with a servlet filter. Check it out at OWASP.

  2. Anonymous

    For ASP.net Is there any by which we can disable the X-Frame-Option of another domain website(Third Party Links), Can we open forcibly the third party links in Iframe.

Comments are closed.