# External scripts use Subresource Integrity hashes

- **Pattern:** `ab-000011` (`security-headers.headers.subresource-integrity`)
- **Severity:** info
- **Lifecycle:** active
- **Last modified:** 2026-04-17
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000011
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000011)

## Why it matters

When your app loads scripts from a CDN without Subresource Integrity hashes, you're trusting that the CDN will always serve exactly the file you expect. CDN compromises happen — an attacker who gains write access to a CDN bucket, a package registry, or a DNS record can replace `jquery.min.js` with a version that exfiltrates every form field on your page. OWASP A08 (Software and Data Integrity Failures) covers this supply chain vector directly. SLSA Level 2 requires artifact integrity verification. CWE-829 (Inclusion of Functionality from Untrusted Control Sphere) and CWE-494 (Download of Code Without Integrity Check) both map to external scripts without SRI.

## Severity rationale

Info because SRI primarily protects against CDN-level compromise, a low-frequency attack that requires third-party infrastructure control to exploit.

## Remediation

Add `integrity` and `crossorigin` attributes to every external `<script>` and `<link rel="stylesheet">` tag. Generate the hash from the exact file version you're pinning.

```html
<script
  src="https://cdn.example.com/lib.min.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8w"
  crossorigin="anonymous">
</script>
```

Generate hashes at https://www.srihash.org/ or via `shasum -a 384 lib.min.js | xxd -r -p | base64`. The long-term fix is to bundle external dependencies rather than loading them from CDNs — then SRI is moot because the asset is yours.

## Detection

- **ID:** `subresource-integrity`
- **Severity:** `info`
- **What to look for:** Count all `<script>` and `<link rel="stylesheet">` tags loading from external CDNs or third-party domains. For each, verify they have `integrity` and `crossorigin` attributes.
- **Pass criteria:** 100% of external script and stylesheet tags (loading from domains other than the site itself) include `integrity` attributes with SRI hashes using at least 1 of: SHA-256, SHA-384, or SHA-512. No more than 0 external resources should lack SRI hashes. Report: "X of Y external resources include SRI integrity attributes."
- **Fail criteria:** Any external scripts or stylesheets are loaded without SRI hashes.
- **Skip (N/A) when:** No external scripts or stylesheets are loaded — all resources are served from the same domain or bundled.
- **Detail on fail:** `"External script from cdn.example.com loaded without integrity attribute"` or `"2 external scripts from third-party CDNs lack SRI hashes"`
- **Remediation:** Subresource Integrity ensures that scripts loaded from CDNs haven't been tampered with:

  ```html
  <script src="https://cdn.example.com/lib.js"
    integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8w"
    crossorigin="anonymous">
  </script>
  ```

  Generate hashes at https://www.srihash.org/ or via `shasum -a 384 lib.js | xxd -r -p | base64`.

## External references

- cwe CWE-353
- cwe CWE-494
- cwe CWE-829
- owasp A08
- slsa L2

Taxons: supply-chain, cryptography-and-secrets

HTML version: https://auditbuffet.com/patterns/ab-000011
