Skip to content

Test your website now

Free, no card. We read only public pages.

Run free audit →

Security · Low severity

Subresource Integrity Missing: Pin Trusted Script Files

Fix missing Subresource Integrity on external scripts. Pin exact bytes, configure CORS, test updates, and distinguish browser checks from scanner heuristics.

Published · Updated

What the check tests

Check
sec.sri - Third-party scripts use Subresource Integrity
Passes when
Cross-origin <script> and <link rel=stylesheet> tags should carry integrity= plus crossorigin= attributes.
Scope
graded on every page crawled
Severity
Low
Fix effort
medium - a working day
Impact when fixed
low

In one paragraph

Subresource Integrity missing means an observed external script lacks the integrity metadata or associated attribute expected by this check. SRI lets browsers reject a resource whose bytes do not match approved hashes. Use it for stable, versioned files with compatible cross-origin delivery. It is not suitable for every changing vendor loader, and a scanner cannot replace testing the browser's actual verification.

Why it matters

External scripts execute with the privileges of the including document. Trust therefore extends to the code and the delivery process that supplies it. SRI limits one supply-chain path by checking that the downloaded bytes match content the publisher intended to approve.

It does not prove the approved code is harmless. A malicious file can have a perfectly valid hash if it was approved incorrectly, and a compromised application that can alter both the script URL and integrity value defeats that particular comparison. Review code provenance and deployment security independently.

Cross-origin integrity verification requires a response the browser can use under CORS rather than an opaque no-cors response. For classic external scripts, crossorigin="anonymous" is the common explicit configuration. Module scripts already have CORS-mode loading semantics, so do not present one missing literal attribute as a universal browser rule across all script types.

How WebAuditOS evaluates this finding

The supplied rule reads server-returned script src tags whose hostname differs from the page after stripping a leading www. It expects both integrity and a non-empty crossorigin value. All matching tags passing those presence tests produce a pass; any missing requirement warns. No cross-host script is not graded.

The check does not compute the hash, fetch dependencies, inspect stylesheets, or discover runtime-injected scripts. It can count an owned asset subdomain as external and can reject a valid bare crossorigin attribute because its parsed value is empty. These are checker limits, not all browser requirements.

How to fix it

  1. Inventory the actual external scripts, including dependencies loaded later by a tag manager. Identify which are immutable versioned library files and which deliberately change at the same URL. Decide whether SRI, self-hosting with an update process, isolation, or another risk control fits each.
  2. Pin a reviewed exact version and obtain the intended bytes from a trustworthy distribution source. A hash copied from the same unverified compromised download does not establish that the file was safe to approve.
  3. Generate an accepted digest for the exact file, for example:
openssl dgst -sha384 -binary library.min.js | openssl base64 -A

Use the resulting Base64 value after the sha384- prefix. Do not leave a placeholder in production.

  1. Add integrity metadata and an appropriate cross-origin setting. An illustrative classic-script tag is:
<script src="https://cdn.example.com/library/1.2.3/library.min.js" integrity="sha384-REPLACE_WITH_REAL_DIGEST" crossorigin="anonymous"></script>

This tag is intentionally incomplete until you replace the example URL and digest. The CDN must permit the relevant CORS request. Confirm its actual response rather than assuming every static host does so.

  1. Use crossorigin="anonymous" explicitly when that is your intended classic-script configuration; it is clearer and satisfies the documented check's non-empty-value expectation. If credentials are required, review the complete CORS and personalised-response design rather than changing the value blindly.
  2. Automate hash updates alongside version updates. Test on staging that the approved file executes and, using a controlled altered copy, that a mismatch is rejected. Watch the browser Console for CORS and integrity failures.
  3. Exercise script-dependent features and verify that caches or edge transformations do not change approved bytes unexpectedly. Minification or rewriting after hash generation can create a mismatch.
  4. Rescan, while retaining browser tests and a vendor dependency inventory. A presence-only pass with the wrong hash means the visitor can still receive a broken page.

What the fix can break

A file changed under the same URL will no longer execute when the hash stops matching. That is intended protection, but it can break a feature until a reviewed update is deployed. Pin versions rather than hashing an uncontrolled latest URL.

Analytics, tag managers, and chat loaders often change without stable versions. Do not add a fixed hash and assume they will keep working. Self-host only where permitted and operationally supportable; you then own the update process.

SRI on one loader does not automatically verify every later resource it injects. Maintain complementary CSP and dependency controls rather than presenting it as complete third-party isolation.

Questions

Does a valid hash prove the script is safe?

No. It proves a match to approved bytes, not that those bytes are trustworthy or vulnerability-free.

Why does the scanner pass a script the browser blocks?

It checks attributes, not digest correctness or actual CORS delivery. Inspect the browser's rejection reason.

Must a bare crossorigin attribute fail in a browser?

No. A bare attribute can have anonymous semantics. The documented scanner's empty-value limitation is stricter than that HTML behaviour.

What should I review next?

Review third-party script inventory and CSP.

Standards and sources

  • W3C SRI

In the report

Test this on your own site

Every scan runs sec.sri on every page it crawls, on every plan. The finding carries this id, so a line in a report can be matched to the explanation above - and the free scan needs no account.