Supply Chain Attack Prevention: Protect Your Website from Compromised Dependencies
Supply chain attacks have become one of the most dangerous vectors in web security precisely because they exploit trust. When a malicious actor compromises a dependency your website relies on — an npm package, a CDN-hosted script, a GitHub Action — they inherit all the trust you've extended to that component. Your defenses don't trigger because, from your infrastructure's perspective, the code is coming from a legitimate source.
Is your site exposed? Run a free ZeriFlow scan →
What Is a Software Supply Chain Attack?
A supply chain attack targets the tools, libraries, and services that feed into your software rather than your application directly. Instead of exploiting a vulnerability in your code, attackers compromise something you depend on. The 2020 SolarWinds attack is the most famous example at the enterprise level, but the web ecosystem — npm, PyPI, CDNs, GitHub — has its own persistent supply chain threat.
For website owners and developers, the threat materializes in three main ways: compromised package registry packages, poisoned CDN resources, and malicious CI/CD pipeline actions.
Type 1: Malicious npm and Open-Source Packages
The npm ecosystem hosts over 2 million packages. Attackers exploit this scale through several techniques:
Typosquatting — publishing packages with names similar to popular ones. crossenv (not cross-env), lodash clones, event-stream variants. Developers mistype a package name during npm install and pull down malware.
Dependency confusion — if your organization uses private npm packages with certain names, attackers can publish public packages with the same names at higher version numbers. npm resolves the public version, pulling attacker code into your build.
Account takeover — if a popular package maintainer's npm account is compromised (weak password, no MFA), the attacker publishes a new "update" with malicious code to all existing users. This is how the event-stream incident in 2018 worked, affecting millions of projects.
Abandoned package hijack — an attacker takes over maintenance of an unmaintained package and publishes a malicious update. Popular packages with millions of weekly downloads have been abandoned and later re-registered by malicious actors.
Mitigation:
- Use lock files (package-lock.json, yarn.lock) and commit them to version control. They pin exact versions and hashes.
- Enable npm audit in your CI pipeline and fail builds on high-severity findings.
- Use npm install --ignore-scripts to prevent postinstall scripts from executing arbitrary code on install.
- Scope private packages properly and configure your registry to prevent dependency confusion.
Type 2: CDN and Third-Party Script Compromise
Many websites load JavaScript from third-party CDNs: analytics, A/B testing, payment widgets, chat tools, ad networks. If any of those CDNs is compromised — or if you're loading a file that can be updated by a third party without your knowledge — attackers can inject malicious code that runs in every visitor's browser.
The British Airways formjacking attack (2018) is a textbook example: attackers injected 22 lines of JavaScript into a third-party script loaded by the payment page. Over 400,000 customers had their payment details exfiltrated. The script had been loading from a CDN with no integrity verification.
Subresource Integrity (SRI) is the direct defense. When you include an external script with an SRI hash, the browser verifies the file's content against the hash before executing it:
<script
src="https://cdn.example.com/library.min.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous">
</script>If the file's content changes — even by a single byte — the browser refuses to execute it. The attack is neutralized before it runs.
ZeriFlow checks whether external scripts on your pages include valid SRI hashes, and whether your CSP header reinforces this policy.
Check your SRI and CSP configuration →
Type 3: GitHub Actions and CI/CD Pipeline Poisoning
GitHub Actions workflows are increasingly targeted. Common attack patterns:
Malicious third-party actions — uses: some-org/some-action@v1 pins a version tag, but tags in git can be force-pushed. If v1 is updated to point to a malicious commit, your workflow runs attacker code with access to your secrets.
Pull request poisoning — for public repositories, attackers open PRs that modify workflow files, hoping maintainers merge without scrutinizing the YAML changes.
Self-hosted runner compromise — self-hosted runners with insufficient isolation can be exploited by malicious PRs to access internal network resources or exfiltrate secrets.
Mitigation:
- Pin Actions by commit SHA, not tag: uses: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45769f953675
- Use tools like Renovate or Dependabot to receive PRs when pinned SHA commits update.
- Restrict GITHUB_TOKEN permissions to the minimum required (permissions: read-all by default, explicit write grants only where needed).
- Never pass secrets to workflows triggered by pull_request from forks.
Content Security Policy as a Last Line of Defense
Even if a supply chain compromise occurs, a properly configured Content Security Policy (CSP) limits what the injected script can do:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; connect-src 'self' https://api.yoursite.comWith this policy in place:
- Scripts from any domain not in script-src are blocked from executing.
- XHR/fetch requests to domains not in connect-src are blocked — preventing data exfiltration.
- Inline scripts are blocked by default, neutralizing many injection attacks.
CSP doesn't prevent compromise of a trusted CDN, but it limits attacker capability to the permitted origins and connection targets — significantly constraining what they can steal or do.
Pair CSP with SRI hashes for external scripts, and you've created a configuration where even a compromised trusted CDN can't execute modified code.
Additional Supply Chain Controls
Software Bill of Materials (SBOM)
Generate and maintain a Software Bill of Materials — a machine-readable inventory of every component in your application. Tools like Syft (for containers), CycloneDX, and SPDX produce SBOMs that you can scan against vulnerability databases automatically.
GitHub now supports SBOM export directly from the dependency graph. Knowing what you depend on is a prerequisite for knowing when something goes wrong.
Dependency Review in Pull Requests
GitHub's dependency-review-action automatically comments on PRs that introduce packages with known vulnerabilities or license changes. Integrate it into your workflow:
- name: Dependency Review
uses: actions/dependency-review-action@v3Runtime Application Self-Protection (RASP)
For high-security applications, RASP tools instrument your running application to detect and block anomalous behavior — like a dependency that suddenly tries to read /etc/passwd or make an outbound connection to an unknown IP.
Supply Chain Security Checklist
- [ ] Lock files committed and verified in CI (
npm cinotnpm install) - [ ]
npm auditruns in CI pipeline with high-severity failure - [ ] All external CDN scripts include SRI hashes
- [ ] CSP header restricts
script-srcandconnect-src - [ ] GitHub Actions pinned to commit SHAs
- [ ] Dependabot or Renovate configured for automated dependency updates
- [ ] SBOM generated and scanned for known CVEs
- [ ] MFA enabled on all package registry accounts (npm, PyPI)
FAQ
Q: How common are npm supply chain attacks?
A: Increasingly common. The Socket research team reports hundreds of malicious packages published to npm monthly. Most are caught quickly, but the window between publication and removal is enough for automated CI pipelines to pull them in.
Q: Does SRI work for <link> stylesheets too?
A: Yes. The integrity attribute works for both <script> and <link rel="stylesheet"> tags. It's equally important to apply it to CSS loaded from third-party CDNs, as malicious CSS can exfiltrate form data using CSS attribute selectors.
Q: What if I'm using a CDN and can't predict the hash?
A: For dynamically updated CDN resources where you need the latest version, use your CDN's feature to lock a specific version, then generate and update the SRI hash as part of your deployment pipeline. Tools like sri-toolbox automate this.
Q: Can Subresource Integrity prevent the formjacking attack on British Airways?
A: Yes, precisely. The modified script would have had a different hash than the one declared in the integrity attribute, and the browser would have refused to execute it. SRI is the direct mitigation for CDN-based formjacking.
Q: Does ZeriFlow check for SRI on external scripts?
A: ZeriFlow checks your CSP header configuration, which is the policy layer that enforces SRI requirements. A CSP with require-sri-for script directive, combined with ZeriFlow's header audit, gives you a comprehensive view of your supply chain attack surface.
Conclusion
Supply chain attacks are effective because they bypass your perimeter by hiding inside trusted code. Defending against them requires locking down your dependency management, implementing SRI for all external scripts, and using CSP to contain the blast radius of any compromise that does occur. These are not complex changes — most are configuration adjustments that take under an hour to implement.