Preventing clickjacking using Thinktecture IdentityModel
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
Reblogged this on http://www.leastprivilege.com.
Have a look at the NWebSec Nuget package. Much easier. :)
Looks like a comprehensive library.