- Subresource Integrity TagHelper Using ASP.NET Core – Part 1
- Subresource Integrity TagHelper Using ASP.NET Core – Part 2
What is Subresource Integrity (SRI)
Can you trust your CDN provider? What if they get hacked and the copy of jQuery you are using hosted by them has some malicious script added to it? You would have no idea this was happening! This is where Subresource Integrity (SRI) comes in.
It works by taking a cryptographic hash of the file hosted on the CDN and adding that to your script or link tags. So in our case if we are using jQuery, we would add an integrity and crossorigin attribute to our script tag like so:
The cryptographic hashing algorithm used can be SHA256, SHA384 or SHA512 at the time of writing. In fact, you can use more than one at a time and browsers will pick the most secure one to check the file against.
Scott Helme has a great post on the subject which I highly reccomend you read (It’s where I learned about it).
The ASP.NET Core Tag Helper
I implemented a tag helper for ASP.NET Core MVC 6 which is as simple to use as this:
Don’t you love it when security is so easy! I’m a big believer in making security as easy as having a big red button that says ‘on’ and turning it on by default so people don’t have to. It’s the only way these things will get used! What is it doing behind the scenes?
- Downloads the file from the CDN.
- Calculates a SHA512 hash for the file.
- Adds the integrity and crossorigin attributes to the script tag.
- Adds the SHA512 hash value to the distributed cache (IDistributedCache) built in to ASP.NET Core MVC 6 with no expiry date. If you are using a distributed cache like Redis (Which you should for the pure speed of it) then the hash will be remembered.
- The next time the page loads, the hash is retrieved from the cache, so there is very little performance impact of this tag helper.
There are actually two tag helpers, one supports any tag with a src attribute and another supports any tag with a href element. This is in preperation for when subresource integrity is opened up to tags other than script and link.
In the past, I have often omitted the scheme from the CDN URL like so:
However, I have noticed that Firefox, does not like it when you use SRI and omit the scheme. It stops the file from loading completely. When you think about it, this makes sense. We are trying to confirm that the resource has not been changed, one of the ways to do this is to use HTTPS. It does not make sense to use SRI over HTTP.
The other gotcha I found is that the resource must have the Access-Control-Allow-Origin HTTP header. It can be set to ‘*’ or your individual domain name. Now, I have been using CDN resources provided by Google (for jQuery), Microsoft (for Bootstrap, jQuery Validation etc.) and MaxCDN (for Font Awesome) because they are free, most browsers have probably already got a copy of the files from there and because they have very fast global exit nodes.
However, I have discovered that all provide the Access-Control-Allow-Origin HTTP header except Microsoft on some of their resources. Strangely, they return the header for Bootstrap but not for the jQuery Validation scripts. I have reached out to them through my capacity as an MVP and hope to get the issue solved. In the mean time, if you are using Microsoft’s CDN you can switch to another CDN or wait for them to fix the issue.
Where Can I Get It?
This tag helper is available in a few ways:
- Use the ASP.NET MVC Boilerplate project template which includes this security feature by default.
- The ASP.NET MVC 6 Boilerplate Framework NuGet package. Note that I will be renaming this package when RC2 comes out to be in line with it’s new naming convention.
- Check out source code in the GitHub page for ASP.NET MVC Boilerplate (Search for subresource integrity).