DEV Community

Thomas Ardal
Thomas Ardal

Posted on • Originally published at blog.elmah.io

Content-Security-Policy in ASP.NET MVC

In the previous post, Improving security in ASP.NET MVC using custom headers, I skipped talking about the Content-Security-Policy header entirely. It is not harder to implement, but since it requires a bit more explanation to understand, the header now has its own post. As a small teaser, I will show you an easy way to implement the Content-Security-Policy header using elmah.io in the next post.

The Content-Security-Policy header, is an HTTP response header much like the ones from the previous post. The header helps to prevent code injection attacks like cross-site scripting and clickjacking, by telling the browser which dynamic resources that are allowed to load.

Let's start with a simple example:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Content-Security-Policy" value="default-src 'self'" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

The value of the Content-Security-Policy header is made up of x segments separated by a semicolon. In the example above, we only specify a single segment, saying "only load resources from self". self translates to the same origin as the HTML resource. With this minimum configuration, your HTML is allowed to fetch JavaScripts, stylesheets, etc. from the same domain that served the HTML referencing the resources. You won't be able to include external scripts from CDNs and similar.

Let's say that you host everything yourself, but want to include jQuery from cdnjs. You would need the following value to allow the browser to make requests outside your origin:

<add name="Content-Security-Policy" value="default-src 'self' https://cdnjs.cloudflare.com" />

Remember the segments I talked about? You can configure which domains to load different kind of resources from using a range of different *-src keys like this:

<add name="Content-Security-Policy" value="default-src 'self'; script-src 'self' https://cdnjs.cloudflare.com; style-src 'self' https://maxcdn.bootstrapcdn.com" />

This configuration lets your web application load resources from its own domain plus scripts from cdnjs.cloudflare.com and stylesheets from maxcdn.bootstrapcdn.com. The combinations are endless, so check out the documentation on Mozilla.org for details.

Chances are, you don't have a document where every dependency of your website is written down. Implementing the Content-Security-Policy header therefore takes time and digging. The best approach is to start limiting resources to self and testing the entire web application and see if it works or not. If running with developer tools open in Chrome or whatever browser may be your favorite, the Console will tell you when your web app tries to fetch or execute code not allowed in the header:

Content-Security-Policy results in the console

Another approach to catching all needed configuration, is to start by using an alternative header named Content-Security-Policy-Report-Only:

<add name="Content-Security-Policy-Report-Only" value="default-src 'self'" />

By adding this header instead of Content-Security-Policy, the browser will keep telling when something isn't allowed, but allow it anyway. This way you can keep an eye on the console when running your website in production. When all error messages in the console are gone, you switch back to the original header.

Would your users appreciate fewer errors?

elmah.io is the easy error logging and uptime monitoring service for .NET. Take back control of your errors with support for all .NET web and logging frameworks.

➡️ Error Monitoring for .NET Web Applications ⬅️

This article first appeared on the elmah.io blog at https://blog.elmah.io/content-security-policy-in-asp-net-mvc/

Top comments (0)