TL;DR: obfuscated JavaScript and CSP evasion
- Passes by declaration: Obfuscated JavaScript passes CSP by declaring only what CSP allows. The malicious behavior starts after the script loads.
- Domains, not integrity: CSP allowlists domains, not code integrity. A compromised trusted domain still passes. Polyfill.io passed CSP on 490,000 sites.
- Compliance needs more: 6.4.3 and 11.6.1 require detection beyond CSP: script inventory, integrity verification, tamper detection.
Short on time? See cside's in-browser Magecart and skimmer blocking. It covers everything below in one deployment.
Three routes obfuscated code uses to bypass CSP
CSP controls sources, not payloads. Three attack patterns exploit this:
Trusted CDN or third-party host compromise. The script loads from a domain already on the allowlist. A changed payload does not trigger CSP because the source URL is unchanged. Polyfill[.]io, Magecart web skimming attacks, and recent analytics CDN compromises all follow this route.
First-party file injection. An attacker with server access injects obfuscated code into an existing first-party JavaScript file. That file loads from the site's own domain, which is always permitted.
Dynamic code construction at runtime. An approved script loads and assembles a malicious function from string fragments at runtime, using eval() or Function() or indirect equivalents. The dangerous payload never exists in any loaded resource; it is built inside the browser after a clean page load.
None of these routes violate a source allowlist. CSP reports clean while obfuscated malware executes.
How obfuscated scripts evade automated scanners too
Obfuscation removes the readable signals that both human reviewers and automated scanners look for:
| Technique | What it does | Why scanners miss it |
|---|---|---|
| String splitting and concatenation | Breaks URLs and keywords into fragments joined at runtime | No complete string appears in the static source |
| Base64 encoding with dynamic decode | Stores payload as a blob decoded only at execution | Looks like data, not executable code, to a static analyzer |
| Hex or Unicode escape sequences | Encodes characters as \x61 or A | Static tools must execute the code to resolve the real value |
| Randomized variable names | Replaces readable identifiers with random short names | Removes the keyword signal pattern matchers rely on |
| Late-stage dynamic loading | Fetches the real payload from a C2 server after an approved script runs | The loaded resource differs on every scan |
Subresource Integrity (SRI) hashes defend against silent payload swaps from known sources, but only when you can pin a hash for each file. Third-party scripts that update frequently make SRI impractical in production, which is the core challenge in script integrity management for dynamic scripts. SRI also cannot protect against payloads fetched dynamically from a C2 endpoint, because that payload was not present when any hash was computed.
Why static scanners miss a hijacked CDN
Static analysis and software composition analysis tools parse code before it runs. They find packages with published CVEs, insecure patterns such as innerHTML assignments from user-controlled input, and outdated dependencies. What they cannot do is observe what a CDN actually delivers to a visitor's browser.
The polyfill[.]io incident is the clearest example. When the domain was acquired by Funnull in February 2024, the source code of every site embedding the script was unchanged. The CDN began injecting malicious JavaScript into the responses it served, but only for mobile users, only with a spoofed referrer, and only when the visitor lacked a cookie pattern associated with Google Analytics and developer tools.
A static scanner would have seen <script src="https://cdn.polyfill[.]io/v3/polyfill.min.js"> in the HTML and matched it against no CVE. There was no stable hash to pin either: the endpoint generated a response per request, which is exactly the case where SRI does not apply. The attack was invisible to every code-at-rest tool. By the time researchers identified the payload in June 2024, an estimated 490,000 websites were serving it to real users.
Conditional delivery is what makes this class hard to catch from outside the session. Attackers gate payloads on user agent, referrer, geography and time of day precisely to stay out of synthetic monitoring and researcher browser profiles. A payload that fires only for mobile users in one country on one afternoon never appears in a static scan and does not reproduce in a crawler.
Approaches to obfuscated JavaScript protection
| Approach | Source enforcement | Payload inspection | Handles trusted-host compromise | Detects runtime dynamic injection |
|---|---|---|---|---|
| CSP | Yes | No | No | No |
| Subresource Integrity (SRI) | Partial | Hash only | Partial | No |
| WAF or network-layer filtering | Partial | No | No | No |
| Static JavaScript scanning | No | Partial | Partial | No |
| Browser-layer behavioral monitoring | Policy-optional | Yes | Yes | Yes |
Browser-layer monitoring is the only control in this table that survives all three bypass routes described above. It works alongside CSP and covers the payload-visibility gap CSP leaves open.
What to demand from a CSP-evasion-resistant tool
Four questions to ask before shortlisting a vendor:
Runtime payload observation. Does the tool analyze what scripts execute inside the browser, not just which URLs they loaded from? Ask the vendor to demonstrate detection of a script that loads from a trusted domain and calls an unauthorized exfiltration endpoint. If the demo requires a malicious source URL to fire, the tool is source-dependent.
Obfuscated code pattern detection. Ask specifically about string splitting, eval() equivalents, and base64 dynamic decode. Tools that only flag eval() literally will miss most real-world obfuscation.
Post-load behavioral monitoring. Many attacks fetch their real payload from a C2 endpoint after the initial page load. The tool must continue monitoring beyond DOMContentLoaded, not only at initial parse.
Alert explainability. An alert that says only "suspicious script detected" is not actionable. Each finding should identify the script, the behavior that triggered detection, and the network call it attempted, so an analyst can triage without guessing.
How cside fits this picture
cside instruments the browser through a script that runs inside each visitor session. It observes what every third-party and first-party script does at execution time: network calls made, DOM changes applied, sensitive data fields accessed, and obfuscated execution patterns detected.
When a compromised CDN serves an obfuscated payload to a page instrumented by cside, detection fires on what the payload does at runtime (unauthorized network call, obfuscated eval chain, data exfiltration pattern) rather than on where it loaded from. A source allowlist failure cannot produce a false negative in a behavior-based system.
PCI DSS v4.0.1 requirements 6.4.3 and 11.6.1 (mandatory since March 2025) require merchants to authorize all scripts on payment pages and detect unauthorized modifications to script content or HTTP headers. Browser-layer behavioral monitoring provides the execution-level evidence those controls expect from a monitoring layer that reaches inside the browser rather than stopping at the network edge.
For more on where CSP falls short in practice, see why CSP doesn't work. For a technical breakdown of obfuscation methods used in real attacks, see the guide to deobfuscating third-party JavaScript.








