Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core Script Tag Helper asp-fallback-src fails integrity check

I'm receiving the following error when I test falling back to a local file using the ASP.NET Core Script Tag Helper:

Failed to find a valid digest in the 'integrity' attribute for resource 'http://localhost:48888/js/jquery.min.js' with computed SHA-256 integrity 'oozPintQUive6gzYPN7KIhwY/B+d8+5rPTxI1ZkgaFU='. The resource has been blocked.

The local file is text equal to the CDN version, but is not binary equal. This becomes a problem because the integrity hash is compared against not only the main source, but the fallback source as well, and fails the check because it generates a different hash.

Here is an example:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"
    asp-fallback-src="~/js/jquery.min.js"
    asp-fallback-test="window.jQuery"
    crossorigin="anonymous"
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=">
</script>

This works fine as long as the browser can reach the Google's CDN. But if you change source to bad value such as looking for a non-existent version such as "3.9.9" which causes it to fallback to the local file. That local file will fail to load because they are not binary equal (different hashes).

Ideally the integrity check would not be applied to local files, since we trust a local file under our control. The alternative is that we could define a different hash for the local fallback.

Are either of these options available? If not is there another workaround? I'm trying to avoid manually copying down from the CDN to make them match, because of the added maintenance work required for future updates. I'd like to use a package manager.

like image 584
Josh Avatar asked May 30 '18 17:05

Josh


3 Answers

With recently released ASP.NET Core 2.2.0 from December 2018 both LinkTagHelper and ScriptTagHelper gained new boolean property asp-suppress-fallback-integrity. When set to true, fallback resource will bypass the integrity check.

This is necessary when CDN and NPM distribution are binary different like is the case for Font Awesome 5.

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"
          asp-fallback-href="~/lib/font-awesome/css/all.min.css"
          asp-fallback-test-class="fab" asp-fallback-test-property="font-style" asp-fallback-test-value="normal"
          asp-suppress-fallback-integrity="true" />

On a personal note, I see no gain in having integrity check on local resources. It is high maintenance and is running high risk of invalidating fallback which is disastrous and without complex testing requiring simulation of failing CDN with every new version, hard to spot. Therefore I prefer to add this property to all resources.

like image 154
Xeevis Avatar answered Nov 14 '22 10:11

Xeevis


Currently, there is no an out-of-the-box solution and it is not clear when it will be implemented (see here). Moreover, I also had this problem and I couldn't find a graceful workaround. Nevertheless, we have two options here:

  1. Implement an own ScriptTagHelper using its source code and exclude the integrity attribute from FallbackBlock.
  2. Not to use ScriptTagHelper and write what it produce manually except the integrity attribute in FallbackBlock:
<script 
    src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" 
    crossorigin="anonymous" 
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=">
</script>
<script>(window.jQuery||document.write("\u003Cscript src=\u0022\/js\/jquery.min.js\u0022 crossorigin=\u0022anonymous\u0022 \u003E\u003C\/script\u003E"));</script>
like image 37
AlbertK Avatar answered Nov 14 '22 11:11

AlbertK


Option 1

You can stop using a CDN and serve the file from the NPM package instead. You can run your site behind a service like Cloudflare which can cache the files globally for you.

Option 2

Add a step to your build (webpack, gulp or whatever) to copy the file from the CDN directly. I'm not sure why their file is not binary equal.

Option 3

If either of the above options is too hard, you can stop using SRI. It's a cost vs value equation. Only you can decide if it's worth the effort. I don't think you can switch out the hash depending on whether it's a local or remote file.

like image 1
Muhammad Rehan Saeed Avatar answered Nov 14 '22 09:11

Muhammad Rehan Saeed