Skip to content

Preventing clickjacking using Thinktecture IdentityModel

July 3, 2013

I don’t know why it’s taken me this long to add anti-clickjacking support, but I finally needed it myself today so I added it to Thinktecture IdentityModel. If you’re not familiar with clickjacking, it’s an attack where your HTML is loaded into an <iframe> and the end user is tricked into clicking links or buttons in you app without their knowledge. To thwart clickjacking each of your pages needs to emit an X-Frame-Options HTTP response header to inform the browser your application’s requirements for running in an <iframe>.

To emit the X-Frame-Options HTTP response header I devised a FrameOptionsAttribute MVC response filter class. To protect a page in MVC you’d simply apply the [FrameOptions] attribute to a controller or action method and the filter will emit the X-Frame-Options header. By default DENY is emitted (the most restrictive/secure option), but the constructor overloads allow other options. Here are a few examples (from the sample) of how you’d use it:

[FrameOptions]
public ActionResult DenyImplicit()
{
    return View();
}

[FrameOptions(FrameOptions.Deny)]
public ActionResult Deny()
{
    return View();
}

[FrameOptions(FrameOptions.SameOrigin)]
public ActionResult SameOrigin()
{
   return View();
}

[FrameOptions("http://localhost:23626")]
public ActionResult CustomOrigin1()
{
   return View();
}

[FrameOptions("http://foo.com")]
public ActionResult CustomOrigin2()
{
   return View();
}

The FrameOptions.Deny setting indicates that the response is never allowed in an <iframe>. FrameOptions.SameOrigin indicates that the response is only allowed in an <iframe> if the hosting page is from the same origin. FrameOptions.CustomOrigin indicates that the response is only allowed in an <iframe> if the hosting page is from the specified origin (which is passed to the FrameOptionsAttribute constructor).

If the origin needs to be generated dynamically, you can derive from the FrameOptionsAttribute class and override the GetCustomOrigin method, as such:


public class MyDynamicFrameOptionsAttribute : FrameOptionsAttribute
{
   public MyDynamicFrameOptionsAttribute()
      : base(FrameOptions.CustomOrigin)
   {
   }

   protected override string GetCustomOrigin(HttpRequestBase request)
   {
      // do your DB lookup here
      if (request.Url.Host == "someHostITrust" || request.Url.Host == "localhost")
      {
         var origin =
            request.Url.Scheme +
            "://" +
            request.Url.Host + (request.Url.Port == 80 ? "" : ":" + request.Url.Port);
         return origin;
      }

      return null;
   }
}

HTH

4 Comments leave one →
  1. July 4, 2013 1:08 am

    Reblogged this on http://www.leastprivilege.com.

  2. July 4, 2013 4:03 am

    Have a look at the NWebSec Nuget package. Much easier. :)

Trackbacks

  1. Hawk Support in Thinktecture IdentityModel v3.3 | www.leastprivilege.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com 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

%d bloggers like this: