← All checks
SecurityTypical severity: Low

Subresource Integrity Scanner

Detects scripts and styles loaded from external CDNs without the integrity attribute that verifies them.

What it checks

This scanner reviews the scripts and stylesheets your page loads from CDNs or external origins and checks whether they include the integrity attribute. That attribute lets the browser verify that the file it received is exactly the one expected.

Why it matters

Without the integrity attribute, if the external CDN is compromised or tampered with, your site would run modified code without noticing. An attacker could inject malicious scripts that steal your users' data straight from their browser.

How to fix it

Add the integrity attribute with the file's hash to every script and style you load from an external origin, along with crossorigin. Many tools and the CDNs themselves provide the hash ready to copy, or you can self-host the resource instead.

How this check works

Scanaris walks through the HTML of your main page and looks at two kinds of tag: <script src="..."> and <link rel="stylesheet" href="...">. It resolves each URL against the page's and treats it as external if its origin (scheme, domain and port) differs from yours; that includes URLs starting with //, which load from the CDN with the page's protocol. It ignores data: and blob:. For each external resource it checks for the integrity attribute; if missing, it notes it. If there is at least one, it opens a low-severity finding with the number of resources and the first ten URLs. Scripts and styles from your own domain are not flagged: SRI adds nothing there.

Why it matters

When you load a library from a CDN, you are running in your users' browsers whatever that CDN decides to serve. If the CDN is compromised, or if its domain changes hands, the file can be replaced by one that does the same thing and also steals form data or redirects to scams. It happened in June 2024 with polyfill.io: the domain was sold, the script started injecting malicious code and more than a hundred thousand sites that included it served it without noticing. The integrity attribute holds the hash of the file you reviewed; the browser hashes what it downloads and, if it does not match, refuses to run it. It is low severity because it requires the CDN to be attacked first, but when that happens the damage is total and silent.

How to fix it

Option 1: add integrity to the tags

<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"
  integrity="sha384-..." crossorigin="anonymous"></script>

You get the hash by downloading the exact file and running:

curl -s https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js | openssl dgst -sha384 -binary | openssl base64 -A

cdnjs and jsDelivr show a ready-to-copy hash next to each file. The crossorigin="anonymous" attribute is required so the browser can verify a resource from another origin. And the URL must point at a pinned version (@4.4.0), never at latest: if the CDN updates the file, the hash stops matching and your site stops loading that library, which is exactly what you want to happen on an unreviewed change.

Option 2: serve the libraries from your own domain

Install them with npm and let your bundler (Vite, webpack, Nuxt, Next.js) include them in your build. The file then comes from your server, with a hash in its name, and SRI is no longer needed. It is the usual choice in modern projects and the one that resolves the finding at the root.

What cannot use SRI

Google Fonts stylesheets change depending on the browser requesting them, so their hash is not stable: either accept that finding or self-host the fonts (which also improves privacy and speed). Analytics and ad scripts that update themselves (gtag.js, the Meta pixel) cannot take a fixed hash either; there the defence is CSP, which limits what each origin can do and is measured by weak CSP.

Check it is fixed

curl -s https://yourdomain.com | grep -oE '<(script|link)[^>]*(src|href)="(https?:)?//[^"]+"[^>]*>' | grep -v integrity

Every line that comes out is an external resource without integrity. If only the ones that cannot take it remain (fonts, analytics), you are done.

Frequently asked questions

Does SRI slow down loading?

Not noticeably: computing a SHA-384 hash of a file a few hundred kilobytes in size takes milliseconds. What it does do is force you to pin versions, which is good practice anyway.

If I update the library, do I have to change the hash?

Yes, and that is the point: the update goes through your hands. If you use npm and your bundler, the process is the same as always and the build handles the hash.

What about old versions of libraries on the CDN?

SRI guarantees the file is the one you chose, not that it is safe. A jQuery 1.12 with the correct hash still has its flaws; that is detected by outdated libraries.

Check it on your site

Scan your site free and see if this and 44 other checks pass, with a fix prompt for every issue.

Scan my site free

Related checks