ASP.NET Anti-forgery configuration

Home / ASP.NET Anti-forgery configuration

ASP.NET has some useful security options to prevent cross-site scripting, click hijacking, and other vulnerabilities. However, configuring these options has a few caveats.


The AntiForgeryConfig options are provided in the System.Web.Helpers namespace.

The first option, if you’re using claims-based authentication, is the UniqueClaimTypeIdentifier. If this isn’t set, ASP.NET will look for these claims:

http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider

If those claims are not found, then ASP.NET will throw an exception. In my projects, I generally don’t use these claims. Instead, I use the DefaultNameClaimType to identify logged-in users. For that case, the configuration looks like this:

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimsIdentity.DefaultNameClaimType

ASP.NET MVC has a simple helper to help prevent cross-site scripting attacks. To accomplish this, we can render an anti-forgery token in our view with a simple Html extension:

@Html.AntiForgeryToken()

There is a gotcha with this helper, though. When the AntiForgeryToken is present, ASP.NET will also attempt to prevent click hijacking from IFrames by appending this Http header:

X-Frame-Options: SAMEORIGIN

The problem, here, then is that if you forget about this and are legitimately developing applications across different origins that must open each other in IFrames, you applications will fail. Fortunately, we can turn this x-frame header off:

AntiForgeryConfig.SuppressXFrameOptionsHeader = true;

I personally still like to keep the header, but configure it. We can do this in the web.config:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <clear />
      <add name="X-Frame-Options" value="ALLOW-FROM https://my.othersite.com" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

The nice thing about this approach is that we can transform the configuration based on our deployment environment appropriately.

Finally, another useful feature is to force HTTPS. This has to be handled by attaching both a global filter and an AntiForgeryConfig option. MVC controllers have an out-of-the-box filter for requiring HTTPS, but ApiControllers do not. The code snippet below includes the RequireHttpsFilterAttribute:

public static class GlobalConfig
{
    public static void CustomizeConfig(HttpConfiguration config)
    {
        // Require SSL for all requests
        GlobalFilters.Filters.Add(new RequireHttpsAttribute());
        config.Filters.Add(new RequireHttpsFilterAttribute());

        // Set antiforgery config
        AntiForgeryConfig.RequireSsl = true;
    }
}

public class RequireHttpsFilterAttribute : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
        {
            actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
            {
                ReasonPhrase = "HTTPS Required"
            };
        }
        else
        {
            base.OnAuthorization(actionContext);
        }
    }
}

On a side note, I also like to expressly specify how to handle certificate validation using the SevicePointManager. This is helpful, especially when debugging, to ignore cert errors. Keep in mind, you should not ignore cert errors in a production environment:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;

#if DEBUG
    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(AcceptAllCertifications);
    ServicePointManager.DefaultConnectionLimit = 5000;
#endif


private static bool AcceptAllCertifications(object sender,
    System.Security.Cryptography.X509Certificates.X509Certificate certification,
    System.Security.Cryptography.X509Certificates.X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }

Microsoft’s documentation on the anti-forgery options is sparse, but sufficient once you understand the implications:

https://msdn.microsoft.com/en-us/library/system.web.helpers.antiforgeryconfig.suppressxframeoptionsheader(v=vs.111).aspx
https://msdn.microsoft.com/en-us/library/system.web.helpers.antiforgeryconfig.uniqueclaimtypeidentifier(v=vs.111).aspx
https://msdn.microsoft.com/en-us/library/dd470175(v=vs.118).aspx

Leave a Reply