Back to Blog
Supply Chain Attacks in Web3 — From NPM to Protocol Exploits
PentestingWeb3 SecurityAudit

Supply Chain Attacks in Web3 — From NPM to Protocol Exploits

SulfurPT
SulfurPT
12 min

TL;DR — The 5 Vectors Draining Web3 Projects

  • Malicious package releases hijack wallet transactions (npm 2025: 18 packages, 2B weekly downloads)
  • Compromised maintainer accounts poison official libraries (@solana/web3.js, @dydxprotocol/v4-client-js, ~50M monthly downloads)
  • Supply chain attacks via package confusion trick build systems into installing malicious packages (theoretical risk in DeFi)
  • Phishing attacks via package names exploit typos to deliver crypto-stealers (solana-py, truffle-vscode)
  • CI/CD injection injects malicious code during bundling — source code stays clean, final bundle is weaponized
Your JavaScript dependencies are direct access to user funds. Your build pipeline is the forge where trust is minted — or broken.

The Reality: Supply Chain Attacks Are DeFi Attacks

In 2024, 14 of 23 crypto-focused supply chain campaigns targeted npm (The Hacker News). In the September 2025 attack Wiz reported that around 10% of analyzed cloud environments contained at least one of the compromised packages (Wiz.io analysis).
This changes everything for Web3:
  • Frontends bundle JavaScript that executes in users' wallets
  • Malicious code intercepted wallet calls and modified transaction recipients before signing
  • Build pipelines (CI/CD) automatically pull updates from compromised sources
  • Attackers specifically target crypto infrastructure
This article breaks down the five critical attack vectors with real incidents and a practical checklist.

1. Malicious Package Releases: The npm Mass Compromise (Sept 2025)

What happened: On September 8, 2025, threat actors phished maintainer Josh Junon via npmjs.help and published malicious versions of 15+ widely-used packages in a 2-hour window:
Collectively, these packages account for more than 2 billion weekly downloads.
How it worked: Attackers intercepted browser APIs (fetch, XMLHttpRequest) and wallet calls (window.ethereum.request, Solana signing). The malware scanned for blockchain addresses (ETH, BTC, SOL, LTC, BCH, TRX) and modified transaction recipients to attacker wallets, using look-alike addresses to avoid detection.
Impact:
  • Any frontend bundling these versions served malicious code to users
  • Malicious transactions were signed before users detected anything
  • Teams had to halt releases, rebuild, and audit dependencies
  • The attack disrupted development pipelines across the ecosystem
Why it succeeded:
  • Trusted maintainer account — npm users automatically trusted the packages
  • Extremely high download volume — these utilities are ubiquitous
  • Obfuscation hid malicious code among legitimate functionality

2. Compromised Maintainer Accounts: Official Libraries Poisoned

When attackers gain publishing credentials to legitimate packages, they bypass all trust assumptions. Two major incidents show this pattern:

@solana/web3.js Backdoor (Dec 2024)

On December 2, 2024, attackers published malicious versions of @solana/web3.js (v1.95.6, v1.95.7) using a compromised maintainer account. This is the official Solana JavaScript library with ~50M monthly downloads and 3,000+ dependent projects.
The backdoor function addToQueue exfiltrated private keys to sol-rpc[.]xyz. Analysis by ReversingLabs found 14 modified files with C2 URLs (ReversingLabs research). GitHub advisory: "Any computer that has this package installed or running should be considered fully compromised."
Key differences from phishing attacks:
  • Attackers controlled the legitimate package — no typos needed
  • Every automatic updater (Dependabot, npm-check-updates) was at risk
  • Blast radius was massive — potentially thousands of dApps affected
What went wrong: Social engineering compromised the maintainer's publish-access account. The malicious code remained live for 5.5 hours before detection and removal.
Lessons:
  • Even official, well-maintained libraries can be weaponized
  • Trust must be verified continuously — monitor maintainer activity, enforce 2FA, use hardware keys
  • Pin exact versions and review all dependency changes manually for production
  • Incident response windows are critical — every hour matters
Real-world impact: Incident response teams reported scrambling to isolate affected machines, force key rotations, and rebuild from clean caches under intense pressure. One DeFi team had to evacuate keys from three machines within an hour after the advisory.

dYdX Breach: Coordinated Account Takeover (Jan 2026)

On January 27, 2026, attackers published malicious versions of @dydxprotocol/v4-client-js (npm) and dydx-v4-client (PyPI) using compromised publishing credentials. This was a direct account takeover of the official dYdX developer accounts.
The attackers released versions 3.4.1, 1.22.1, 1.15.2, and 1.0.31 on npm, plus 1.1.5post1 on PyPI — all appearing as legitimate updates from the official maintainers.
npm payload: Wallet stealer embedded in registry.ts, exfiltrating seed phrases to dydx.priceoracle[.]site
PyPI payload: Wallet stealer + Remote Access Trojan (RAT) for arbitrary code execution
dYdX's response: "Any machine that has these packages installed should be considered compromised" (source) — see Socket.dev's technical analysis for details (Socket.dev analysis).
Key insight: Both attacks demonstrate the same pattern — attackers don't need vulnerabilities when they own the keys. The dYdX incident shows escalation: simultaneous compromise across two ecosystems (npm + PyPI) with sophisticated payloads.

3. Supply Chain Attacks via Package Confusion

The Mechanism
Discovered by Alex Birsan, dependency confusion exploits how package managers resolve internal vs public dependencies:
  1. Company uses internal package @company/auth (private registry)
  2. Package name leaks via GitHub, config files, or frontend bundles
  3. Attacker publishes @company/auth to public npm with higher version number
  4. Build system prefers public package → executes attacker code
Why DeFi is vulnerable:
  • Internal package names (@yourprotocol/cli) often exposed in frontend bundles
  • CI/CD systems auto-pull latest versions from public registries
  • Most teams use pip --extra-index-url (adds public index) instead of --index-url (replaces with private only)
  • High-value targets: packages handling transaction signing or wallet management
Root cause: Package managers choosing highest version regardless of source (pip --extra-index-url behavior, some Artifactory virtual repo configs).
Fix:
  • Reserve internal packages names in public registries to prevent external publication
  • pip: use --index-url (point exclusively to private index, never --extra-index-url)
  • npm: separate internal and external registries; don't mix in one virtual repository
  • Scan public repositories for leaked internal package names
Note: While no major DeFi protocol has publicly confirmed a dependency confusion breach, the attack surface is enormous and theoretically exploitable.

4. Phishing Attacks via Package Names

The September 2025 npm attack started with npmjs.help — a domain used for phishing maintainers. This attack works because:
  1. High-stakes context — Developers working under pressure (token launch, audit deadline)
  2. Complex package names@solana/web3.js, ethers-ts, viem-utils
  3. Cross-ecosystem discrepanciessolana (PyPI) vs solana-py (GitHub)
  4. Newcomer influx — Many developers unfamiliar with exact package names
Recent Web3 examples:
  • solana (PyPI) vs solana-py (GitHub) — malicious Solana Python API stealing crypto keys (Sonatype report)
  • truffle-vscode vs truffle-for-vscode — exfiltrated secrets from wallet developers (Mend.io)
  • bip39 variants — targeted BIP39 wallet generators
Defenses:
  • Copy-paste package names directly from official documentation
  • Always verify: download count, maintainer, publication date, verified publisher badges
  • Use scoped packages (@solana/web3.js) — harder to spoof
  • Implement pre-install hooks that check packages against known typosquat blocklists
  • Include package verification as part of developer onboarding and code review processes

5. CI/CD Injection: The Invisible Threat

The Mechanism
Build-time dependency injection occurs when the build toolchain itself is compromised—not the packages, but the tools that produce the final JavaScript bundle. Targets include:
  • Bundlers/build tools: Webpack, Vite, Rollup, esbuild
  • Transpilers: Babel, TypeScript compiler (tsc), SWC
  • Minifiers: Terser, UglifyJS
  • Build plugins: vite-plugin-web3, webpack plugins, Rollup plugins
  • Build scripts: postinstall, prepare, prepublish hooks
How it works:
  1. Source code on GitHub is 100% clean
  2. Build process runs compromised tool/plugin
  3. Malicious code injected into final dist/bundle.js
  4. Deployed frontend serves weaponized bundle
  5. Repository audit shows nothing—the attack lives only in artifacts

Are you audit-ready?

Download the free Pre-Audit Readiness Checklist used by 30+ protocols preparing for their first audit.

No spam. Unsubscribe anytime.

Why Web3 is uniquely vulnerable:
DeFi frontends perform critical operations:
  • Generate signed transactions
  • Call window.ethereum.request()
  • Construct calldata for swaps/approvals
  • Set allowance amounts
A compromised bundler can:
  • Replace recipient addresses
  • Change allowance from router to attacker
  • Increase amounts (type(uint256).max)
  • Swap legitimate calldata for drain functions
Concrete example (AST manipulation):
1// Original in source:
2ethers.sendTransaction({ to: router, value: amount });
3
4// Malicious plugin transforms it to:
5ethers.sendTransaction({ to: attacker, value: type(uint256).max });
The code you review (src/) is not the code users execute (dist/).
Real-world parallels:
  • ua-parser-js — backdoor inserted during publish pipeline
  • SolarWinds — build system compromise injected malicious code into signed updates
Why almost no one talks about this in Web3:
Most audits focus on:
  • Smart contracts ✓
  • npm packages ✓
  • Wallet phishing ✓
But frontend build integrity is rarely verified. The result: perfectly audited contracts get drained because the frontend construct malicious calldata.
Mitigations:
  • Reproducible builds: git clone → npm ci → npm build must produce identical hashes across machines
  • Artifact verification: Deploy only if hash(bundle) == expected_hash (store hash in CI, verify before release)
  • Signed releases: Use Sigstore/Cosign/GPG to sign final bundles; verify signatures in deployment pipeline
  • No dynamic scripts: Avoid postinstall, prepare, prepublish hooks in production packages
  • Immutable CI runners: Use ephemeral, freshly-provisioned runners for builds; never reuse compromised runners
  • Build provenance: Record build environment (dependencies, tool versions, commands) for forensic reproducibility

Conclusion: Your Build Pipeline Is Part of Your Attack Surface

The numbers don't lie:
  • 18 npm packages weaponized in 2 hours (2B weekly downloads)
  • @solana/web3.js — ~50M monthly downloads, 3,000+ dependents, private key theft
  • dYdX compromised via account takeover — publishing credentials stolen
  • 14 of 23 crypto supply chain attacks in 2024 targeted npm (The Hacker News)
  • Build pipeline compromise — source code clean, final bundle weaponized
Old model: "Audit contracts, ignore frontend" — DEAD
New reality: Every dependency and every build tool is a potential transaction hijack vector
Even perfectly audited smart contracts can be drained if the frontend build pipeline is compromised. Security must extend beyond contracts into the entire software supply chain.

Checklist: Secure Your Supply Chain Now

Start here: Check your immediate exposure
1grep -E "debug|chalk|ansi|@solana/web3.js" package-lock.json
Then run this full checklist:
  • Pin exact versions — Remove floating versions (^, ~) from package.json. Use exact versions in lockfiles.
  • Scan for unknown packages — Review package-lock.json / yarn.lock for packages you don't recognize.
  • Audit for internal name leakage — Search GitHub repos and frontend bundles for internal package names that might be public.
  • Verify critical dependencies — Ensure @solana/web3.js, ethers, wagmi, viem are on non-compromised versions.
  • Enable Subresource Integrity (SRI) — Add integrity hashes to CDN-served JavaScript bundles.
  • Block dependency auto-updates — Configure CI/CD to require manual approval for production dependency updates.
  • Use a private registry — Verdaccio, Nexus, or Artifactory with blocklists and allowlists.
  • Clear caches after incidentsnpm cache clean --force on all dev machines and CI runners.
  • Configure package managers correctly--index-url for pip (never --extra-index-url); separate registries for npm; no mixing internal/external sources.
  • Enforce scoped packages — All internal code must use @yourorg/* naming.
  • Monitor maintainer account activity — Set up alerts for publishing events from key maintainer accounts.
  • Verify registry configuration — Ensure npm/yarn/pip are configured to use private registries exclusively where applicable.
  • Implement reproducible builds — Verify that git clone → npm ci → npm build produces identical bundle hashes across clean environments.
  • Artifact verification — Store bundle hash in CI; deploy only if hash matches expected value.
  • Sign releases — Use Sigstore/Cosign/GPG to sign final bundles; verify signatures in deployment pipeline.
  • Avoid dynamic build scripts — Remove postinstall, prepare, prepublish from production packages.
  • Use immutable CI runners — Provision fresh runners for each build; never reuse potentially compromised runners.
  • Record build provenance — Log tool versions, dependencies, and commands for forensic reproducibility.
If any of these fail, stop your next release and remediate now.

Get in touch

At Zealynx, we audit full-stack Web3 security — smart contracts, frontends, and supply chains. Because your users' funds depend on every layer.
Ready to secure your build pipeline? Reach out for a comprehensive supply chain review at zealynx.io/quote.
For more on Web2 infrastructure risks affecting DeFi, see our article on DNS hijacking and frontend compromises.

FAQ

1. Does `npm audit` catch these attacks?
No. Supply chain attacks move too fast for vulnerability databases. You need proactive monitoring, not just CVE scanning.
2. How do I know if I'm already compromised?
Search build logs for affected versions. Scan deployed JavaScript bundles for known malicious patterns. Review on-chain transactions during exposure windows for unexpected recipient changes.
3. Should I stop using npm?
No — but use immutable builds and private registries with strict allowlists. The risk is automatic updates, not the package manager itself.
4. Are Yarn and pnpm safe?
They remain vulnerable to package confusion if misconfigured. The issue is registry configuration, not the client.
5. What about GitHub Dependabot?
It could introduce malicious code if a maintainer account is compromised. Pin versions and review all dependency updates manually for production releases.
6. Do lockfiles protect me?
They prevent accidental upgrades, but if a developer's local cache is already compromised, lockfiles won't help. Always clean install from a clean cache after any security incident.

Glossary

TermDefinition
Supply Chain AttackCompromise of a trusted software component (library, package, build tool) that cascades across multiple organizations.
Phishing AttackSocial engineering technique that deceives users into installing malicious packages or revealing credentials through similar package names or domains.
Subresource Integrity (SRI)Security feature that verifies loaded JavaScript files match a cryptographic hash, detecting tampering.

Are you audit-ready?

Download the free Pre-Audit Readiness Checklist used by 30+ protocols preparing for their first audit.

No spam. Unsubscribe anytime.