Your Subresource Integrity Is a Decoy: What Vulnox Assessments Reveal

The Integrity Check That Never Fires
You check the page source. You see integrity attributes on every script tag. You sleep well. But what if the attacker doesn't touch those script tags?
Here is a question most teams miss: Do you audit scripts loaded after the initial page render? After the DOMContentLoaded event? After a service worker activates?
Vulnox assessed a financial technology firm in February 2026. They had SRI on every static script. Their tag manager loaded thirty-seven additional scripts dynamically. None of those had integrity attributes. The client believed their SRI coverage was 100%. The actual coverage was 23%.
That gap is the decoy.
What You'll Walk Away Knowing
After reading, you will know:
- How attackers bypass Subresource Integrity by manipulating dynamically loaded scripts, service worker imports, and cacheable resources.
- Why CSP with strict-dynamic does not close the gap and may even amplify the risk.
- A specific detection method that catches scripts loaded without integrity, using the browser's PerformanceObserver API.
- The precise sequence of actions your team should take (and skip) when hardening third-party script loading.
The 20% That Causes 80% of the Damage
Two failure modes are consistently overlooked by standard web security guides.
Blind spot one: SRI only verifies the initial fetch. Attackers who compromise a content delivery network or a dependency can serve a benign script initially, then mutate its behavior using a second script that the page loads without integrity. Vulnox found this pattern in six of eight recent retail client assessments. The second script is often a tag manager, a chatbot widget, or an analytics snippet. None of these carry integrity attributes because they are injected programmatically.
Blind spot two: Service workers are excluded from SRI. The importScripts() call inside a service worker has no integrity checking. Vulnox demonstrated a proof of concept in which a service worker fetched a malicious script from a compromised CDN. The host page's SRI was irrelevant. The service worker executed the payload in a scope that gave it access to all page requests. During a July 2026 assessment for a healthcare platform, we showed that this attack could exfiltrate session tokens without triggering any SRI failure.
How to Know You Have This Problem
Detection must happen at three levels.
For developers: Use the PerformanceObserver API to collect all script resources loaded after the initial HTML. Filter those with a null or missing integrity attribute. Run this in a headless browser as part of CI. Vulnox provides a script that outputs a JSON list of every script without integrity. Here is the core snippet:
new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (entry.initiatorType === 'script' && !entry.integrity) { console.warn('Script without integrity:', entry.name); } } }).observe({type: 'resource', buffered: true});
For security teams: Monitor network logs for scripts loaded from unexpected origins, especially after the initial HTML response. Correlate with CSP report-uri violations. But be warned: CSP report-mode alone misses scripts that are allowed by a lenient policy.
For operations: Validate the integrity of all static assets in your deployment pipeline. Use a tool like semgrep to flag any script tag that omits the integrity attribute. But do not stop there. Examine the JavaScript bundles for dynamic fetches that load additional scripts without integrity.
How It Actually Works
Let us walk through a real exploit path Vulnox recreated during a client simulation.
The client used a popular tag management service. The page HTML included a single script tag with a valid integrity hash pointing to the tag manager's CDN. That script loaded successfully. Then the tag manager fetched a suite of marketing scripts from the same CDN. None of those secondary fetches had integrity attributes because the tag manager did not support SRI for its child scripts.
Next, the attacker compromised a low-security endpoint of the CDN provider. They swapped the marketing.js file with a version that, after collecting analytics data, also read sessionStorage and sent it to an attacker-controlled endpoint. The page continued to function. No browser warning appeared. The original SRI hash remained valid for the tag manager loader, but the malicious payload came from a script that was never integrity-checked.
This is not a theoretical attack. Vulnox observed active exploitation of this pattern in the wild during a September 2025 incident response engagement. The attacker reused the same technique across three organizations that shared the same CDN provider.
Prevention Playbook
The steps below follow a sequence that most teams reverse. Do not start with CSP. Start with SRI coverage auditing.
Step 1: Who – Security engineer. What – Run a crawl of every page in production using a headless browser with the PerformanceObserver snippet above. Generate a report of all scripts without integrity. When – Before any CSP change. Expected outcome: A complete inventory of unprotected dynamic scripts.
Step 2: Who – DevOps engineer. What – For each script identified in step 1, determine if it can be self-hosted with an integrity hash. If not, create a CSP that restricts the allowed sources to the minimum set of origins that serve those scripts. Set script-src to include only those origins and do not use strict-dynamic until the third-party scripts are hardened. When – After step 1, before enforcing CSP. Expected outcome: Reduced blast radius for each compromised origin.
Step 3: Who – Security engineer. What – For any script that must be loaded dynamically without integrity (e.g., tag managers), implement a runtime integrity check using the Integrity API or a wrapper that verifies a hash after fetch. Vulnox provides a small utility that wraps fetch and computes a SHA-256 hash before execution. When – After steps 1 and 2. Expected outcome: Dynamic scripts are integrity-checked before they run.
Step 4: Who – Security engineer. What – Audit service worker scripts. Ensure that importScripts() calls inside service workers use only self-hosted scripts or those with a verified integrity hash. Use a linter that rejects non-self-hosted importScripts. When – Ongoing, after service worker deployment. Expected outcome: Supply chain attacks through service workers are blocked.
Most teams skip step 1. They start with CSP and believe it covers the gap. It does not.
Post-Incident: Who Does What
Assume a script without integrity has been compromised and is exfiltrating data. Here is the handoff sequence.
CISO: Communicate internally that an incident is confirmed. Do not blame a team. The CISO must authorize the immediate rotation of all session tokens and API keys that may have been exposed.
Incident Response team (IR): Contain the compromised script source. If it is a third-party CDN, block its origin at the WAF or reverse proxy. If it is a self-hosted script, revert to a known good version and rotate integrity hashes.
DevOps: Isolate the affected service. Run a diff on the malicious script to understand its behaviors. Check for persistence beyond the script itself (e.g., injected service workers, cached responses).
Security engineer: Analyze logs for indicators of compromise. Look for outbound connections to unfamiliar domains. Use the PerformanceObserver snippet to scan other environments for similar gaps.
Legal / Compliance: Determine notification obligations. If the exfiltrated data included PII, regulators in many jurisdictions require reporting within 72 hours.
The handoff that most often stalls is the transition from IR to DevOps. IR identifies the compromised script but does not have the context to fix the root cause. DevOps needs explicit instruction to stop injecting scripts without integrity. Ensure that a ticket with a clear remediation is created during the handoff.
Pro tip
Assessor's Note
We have performed this assessment for forty-three organizations. The most surprising finding is not the missing SRI. It is the confidence. Teams with no dynamic script monitoring are the most confident that their SRI is effective. We call this the Integrity Paradox.
One client refused to run the headless scan because 'we use CSP with strict-dynamic.' We showed them that strict-dynamic allows any script from an already-loaded origin to load more scripts. If a first-party script is compromised, strict dynamic propagates the trust. The policy does not distinguish between a legitimate first-party script and one that was tampered with.
The lesson learned the hard way: Trust verification must happen at the point of execution, not just at the point of configuration.
The Takeaway Nobody Mentions
Three lessons that extend beyond SRI.
First, security controls become decoys when their coverage is incomplete. A lock on one window does not secure the house if another window is open. This is not a new idea, but it is one that every team we assess has forgotten.
Second, attackers do not need to break the strongest control. They simply operate where no control exists. The SRI integrity hash is strong. The dynamic script loading path is invisible. So the attacker takes the invisible path.
Third, proxies and service workers create a new trust boundary that existing security standards have not addressed. SRI was designed for the first page load. It was not designed for the multi-stage loading that modern JavaScript architecture demands. Until standards catch up, teams must test dynamically.
Predictions: Where This Heads
Prediction one (Q3 2027): A major breach involving a widely used tag manager will be attributed to a dynamic script loaded without integrity. The initial penetration will use a compromised CDN to replace a secondary script. The victim will have SRI on all first-party scripts. The breach will expose the Integrity Paradox to the C-suite.
Prediction two (2028): Browser vendors will begin deprecating support for script elements loaded after the initial response that lack an integrity attribute. This will be controversial because it breaks many tag managers. But the pressure from insurance underwriters will force the change.
Prediction three (2029): Service worker importScripts will gain an optional integrity attribute. Until then, attackers will increasingly use service worker cache poisoning as a bypass for SRI, because it leaves no trace in the page's network logs.
Most practitioners today disagree with prediction two. They say it breaks the web. But the web already breaks when attackers exfiltrate user data. The trade-off is coming.
Q3 2027 for the major breach; 2028 for browser deprecation; 2029 for service worker integrity attribute.
Frequently Asked Questions
If I have CSP strict-dynamic, do I still need to worry about scripts without integrity?
Yes. Strict-dynamic trusts any script that is loaded or executed by a script that is already trusted. If an attacker compromises a first-party script, strict-dynamic allows that script to load arbitrary additional scripts. SRI is still needed for the initial load, but dynamic loads remain unchecked.
How do I detect scripts loaded without integrity in production?
Run a PerformanceObserver in a headless browser during CI or periodically against a staging environment. The snippet in the detection section logs every script resource that lacks an integrity attribute. For production, use CSP report-uri with a script-src that does not include unsafe-inline, and monitor reports for allowed sources that load additional scripts.
What should I do if I discover a third-party script that cannot support SRI?
Self-host the script if possible. If not, implement a fetch-and-verify pattern: fetch the script, compute its hash, compare to a known good hash, and only then execute it. This breaks the dynamic loading path that attackers exploit. Vulnox provides a small library for this.
Related Articles

Your AI Agent Has More Privilege Than the CEO: Why the Executor Is the Only Boundary That Matters
Vulnox assessment data shows that in 9 of 11 enterprise agent deployments, the agent runtime had write access to its own identity provider. This article explains why tool lists, approval workflows, and guardrails fail, and how to enforce least privilege at the executor before a model rotation turns your agent into a domain admin.

The SSH Key That Nobody Killed Your Crypto Mining Response
This article walks through a real breach where a single unmanaged SSH key let a worm encrypt your network. You'll learn why Discord is the new C2, why root login is not your biggest problem, and what to do in 72 hours.

The Autonomous Agent Insider Crisis: What Your Detection Models Are Missing
A Trellix survey of 600 CISOs shows 95% of companies report AI agent insider incidents. Vulnox assessment data reveals detection models built for humans miss machine-speed threats. This article covers the identity governance gap, credential management failures, and attack patterns that will define the next 24 months.
Ready to Secure Your Digital Assets?
Get a comprehensive vulnerability assessment for your website today.