Almost every modern website loads code it did not write — a font script, an analytics tag, a charting library, a payment widget. Each of those runs inside your visitors' browsers with exactly the same trust as your own code. That convenience is also your biggest blind spot: if any one of those external files is tampered with, your site silently ships an attacker's code to every visitor.
Also see: Security Headers Checklist 2026, Subdomain Takeover Guide, and Website Security Checklist 2026.
What Is a Supply-Chain Risk? (In Plain Language)
Imagine your website is a kitchen. You cook most dishes yourself, but you also buy a few ready-made sauces from a supplier. A supply-chain attack is when someone poisons the supplier's sauce — you never touched it, your kitchen is clean, but everyone you serve still gets sick.
On the web, the "sauces" are the scripts and styles you load from other companies' servers (CDNs). If an attacker takes over that server, or the company abandons it and someone else claims the address, the code your visitors download changes — and their browsers run it without question. This scanner flags four flavors of that risk:
- Missing Subresource Integrity — you load an external script but never verify it hasn't been swapped.
- Compromised CDN in use — you load from a host with a confirmed, active compromise (e.g. the old
polyfill.io). - Vulnerable library — a known-buggy version of jQuery, AngularJS, etc. with a published CVE.
- Exposed source map — your original, readable source code is downloadable by anyone.
Why This Is One of the Fastest-Growing Attacks
Attackers love supply-chain targets because one compromise scales to thousands of sites at once. The June 2024 polyfill.io incident is the textbook case: a widely-used free CDN changed hands and began injecting malware into an estimated 100,000+ websites overnight. None of those sites were "hacked" in the traditional sense — they simply kept loading a script they had trusted for years.
The uncomfortable truth: your site can be fully patched, behind a firewall, with a perfect password policy — and still serve malware, because the malicious code never lived on your server at all.
Fix 1: Add Subresource Integrity (SRI)
What it does: SRI adds a cryptographic fingerprint to each external file. The browser downloads the file, hashes it, and if the fingerprint doesn't match exactly, it refuses to run it. A swapped or tampered CDN file is blocked automatically — no action from you required after setup.
Before (unprotected):
<script src="https://cdn.example.com/library.min.js"></script>
After (protected):
<script
src="https://cdn.example.com/library.min.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"
referrerpolicy="no-referrer"></script>
How to generate the hash (no tools to install — one command):
# Generate an SRI hash for any URL
curl -s https://cdn.example.com/library.min.js \
| openssl dgst -sha384 -binary \
| openssl base64 -A
# Then paste the output after "sha384-" in the integrity attribute
Prefer a generator UI? srihash.org produces the full tag for you. Reputable CDNs like cdnjs and jsDelivr also show the ready-made SRI tag on every file's page.
SRI only works on files that never change at a given URL (a versioned URL like /jquery@3.7.1/). Never add SRI to a "latest" URL — the file will change, the hash won't match, and your script will stop loading. Always pin an exact version.
Fix 2: Remove Compromised & Abandoned CDNs
If our scanner flagged a compromised CDN, treat it as an active incident — the code is malicious right now:
- Find it: search your HTML, templates and tag manager for the flagged hostname.
- Remove or replace it. For polyfills specifically, move to a safe mirror or self-host only the polyfills you need:
<!-- REMOVE this (compromised) -->
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
<!-- REPLACE with a trusted mirror -->
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js"
crossorigin="anonymous"></script>
<!-- BEST: most modern browsers need no polyfills at all — drop it -->
- Check your tag manager & analytics — these can inject third-party scripts dynamically, outside your HTML.
- Self-host what matters. For critical libraries, download the file and serve it from your own domain. You trade automatic updates for full control — usually the right call for anything on a checkout or login page.
Fix 3: Upgrade Vulnerable Libraries
Old front-end libraries carry publicly documented vulnerabilities (CVEs) that attackers scan for by version number. The fix is almost always "upgrade to the patched version":
# If you use a package manager
npm update jquery # or: npm install jquery@latest
yarn upgrade jquery
# If you pin a CDN version, bump the number
<!-- Before: known-vulnerable -->
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<!-- After: patched + SRI -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
crossorigin="anonymous"></script>
Then re-test the page — major version jumps (jQuery 1.x → 3.x, AngularJS → Angular) can change behavior. Upgrade, click through the key flows, and re-scan to confirm the finding is gone.
Fix 4: Stop Exposing Source Maps
In plain terms: a source map (.map file) is the "answer key" that turns your compressed production code back into the original, readable version — comments, internal routes and all. Great for your own debugging; a gift to an attacker if it's public.
Disable them in your build, or block them at the server:
# --- Disable in your build ---
# Webpack: devtool: false
# Vite: build: { sourcemap: false }
# Create React App: GENERATE_SOURCEMAP=false npm run build
# Next.js: productionBrowserSourceMaps: false (default)
# --- Or block .map at the web server ---
# Nginx
location ~ \.map$ { deny all; return 404; }
# Apache (.htaccess)
<FilesMatch "\.map$">
Require all denied
</FilesMatch>
Still want maps for error monitoring? Upload them privately to Sentry, Datadog, or Bugsnag during your build instead of leaving them in the public web root.
Fix 5: Backstop Everything with a Content-Security-Policy
SRI protects the files you know about. A Content-Security-Policy (CSP) is the safety net for the ones you don't — it tells the browser the only origins allowed to run scripts, so an injected or swapped script from anywhere else is blocked:
# Only allow scripts from your own site + two trusted CDNs
Content-Security-Policy: default-src 'self';
script-src 'self' https://cdnjs.cloudflare.com https://js.stripe.com;
object-src 'none'; base-uri 'self'
See our Security Headers Checklist for a full, framework-by-framework CSP walkthrough.
See Which Third-Party Scripts Put You at Risk
Free scan — detects missing SRI, compromised CDNs, vulnerable libraries and exposed source maps in 60 seconds, with a copy-paste fix for each.
Scan Your Site NowFrequently Asked Questions
What is a supply-chain attack on a website?
It compromises code you load from a third party — a CDN, analytics tag, or JavaScript library — rather than attacking your server directly. Because that code runs in your visitors' browsers with your site's trust, one poisoned dependency affects every visitor.
What is Subresource Integrity (SRI)?
An integrity="sha384-…" attribute on an external <script> or <link>. The browser refuses to run the file if its hash doesn't match, blocking tampered or swapped CDN files automatically. Always pair it with a pinned (versioned) URL.
Why are exposed source maps a security risk?
A public .map file lets anyone reconstruct your original, readable source code — including internal routes and business logic — which attackers use to plan targeted attacks. Disable production source maps or block .map at the server.