DEV Community

Pico
Pico

Posted on

axios Was Attacked. npm audit Showed Zero Issues. Here's What Behavioral Scoring Showed.

axios Was Attacked. npm audit Showed Zero Issues. Here's What Behavioral Scoring Showed.

On April 1st, 2026, the npm package axios — 101 million downloads per week — was compromised. npm audit and Dependabot reported nothing unusual beforehand. A behavioral commitment audit would have flagged it as CRITICAL months earlier.


Here's what you get if you run a standard npm audit on a project that depends on axios:

found 0 vulnerabilities
Enter fullscreen mode Exit fullscreen mode

Nothing. Because npm audit checks against a database of known CVEs. Until the attack is catalogued, it's invisible.

Here's what behavioral scoring returned for axios before the attack:

axios  score=86  1 maintainer  101M downloads/week  🔴 CRITICAL
                 ↑
         maintainerDepth: 4/15
Enter fullscreen mode Exit fullscreen mode

Score of 86 looks healthy. But the CRITICAL flag is triggered by one signal: sole maintainer + >10M weekly downloads. That combination is the attack profile that got exploited.

What happened on April 1st

axios has 101 million weekly downloads. It's embedded in virtually every production JavaScript project. In March, a similar attack hit opentelemetry-instrumentation-openai (the LiteLLM incident) — sole maintainer, 10M+ weekly downloads, credentials compromised, malicious package pushed.

The axios attack followed the same playbook. The attack surface — single maintainer controlling a package with 100M+ weekly downloads — was structural, visible, and had been there for years.

Why npm audit misses this entirely

npm audit is a CVE scanner. It answers: "has a vulnerability been discovered and documented in this package?"

That's a useful tool. But it answers the wrong question for this class of risk.

The question that matters is: "what is the probability that this package becomes the vector for a future attack?"

The answer comes from behavioral signals, not CVE databases:

  • Who maintains it? One person. No corporate backing. If their credentials are compromised, the package is compromised.
  • How widely is it used? 101M downloads/week. That's the reward side of the equation — high-value target.
  • How long has it been maintained? 11.6 years. Old packages that still see massive traffic have accumulated attack interest.
  • When was the last release? 2 days before the attack, a patched version was pushed.

The CRITICAL flag isn't a prediction. It's a structural characterization: this package has the exact profile that attackers look for.

The score breakdown

curl -X POST https://poc-backend.amdal-dev.workers.dev/api/audit \
  -H "Content-Type: application/json" \
  -d '{"packages": ["axios"]}'
Enter fullscreen mode Exit fullscreen mode

Returns:

{
  "name": "axios",
  "score": 86,
  "riskFlags": ["CRITICAL"],
  "scoreBreakdown": {
    "longevity": 25,
    "downloadMomentum": 22,
    "releaseConsistency": 20,
    "maintainerDepth": 4,
    "githubBacking": 15
  }
}
Enter fullscreen mode Exit fullscreen mode

maintainerDepth: 4/15 — that's the signal. Everything else looks fine. Axios is 11.6 years old (full longevity marks), actively downloaded (22/25), regularly released (20/20). The 86 overall score would pass most "healthy package" thresholds.

But 4/15 on maintainer depth, combined with 101M weekly downloads, triggers CRITICAL. The rest of the score being healthy is what makes it dangerous — the package looks safe.

The pattern keeps repeating

Three of the most depended-on packages in the npm ecosystem all carry the same structural risk:

Package Score Maintainers Weekly Downloads Risk
chalk 75 1 412M 🔴 CRITICAL
zod 83 1 151M 🔴 CRITICAL
axios 86 1 101M 🔴 CRITICAL

For comparison:

Package Score Maintainers Weekly Downloads Risk
react 91 2 117M ✅ No flag
lodash 94 3 139M ✅ No flag
express 97 5 92M ✅ No flag
typescript 98 6 171M ✅ No flag

The difference isn't download volume. It's not age. It's maintainer depth. React with 2 maintainers doesn't flag CRITICAL. Axios with 1 maintainer and 101M downloads does.

What CRITICAL means operationally

CRITICAL doesn't mean "stop using axios immediately." It means: this is your attack surface — know it.

For packages you don't control:

  • Pin to a known-good version and verify on updates
  • Watch for unexpected new releases (axios just pushed a version 2 days ago)
  • Don't assume that high download counts mean high security oversight

For packages you do maintain: if you're a sole maintainer with >10M weekly downloads, your credentials are a high-value target. Hardware security keys are not optional.

See what's in your stack

The Commit supply chain scanner flags this automatically. Paste your package.json, scan by name, or drop in a GitHub URL to audit any repo's dependencies.

The GitHub Action posts the risk table directly on your PRs:

- uses: piiiico/proof-of-commitment@main
  with:
    comment-on-pr: true
Enter fullscreen mode Exit fullscreen mode

Or use it from Claude, Cursor, or Windsurf with zero install (MCP):

{
  "mcpServers": {
    "proof-of-commitment": {
      "type": "streamable-http",
      "url": "https://poc-backend.amdal-dev.workers.dev/mcp"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Then: "Audit my package.json for supply chain risk" — it fetches the packages, scores everything, returns a risk table.


The LiteLLM attack happened in March. axios happened April 1st. Both were CRITICAL by behavioral signals before the attack. The question isn't whether your dependencies contain this risk — it's whether you can see it.

Open source: github.com/piiiico/proof-of-commitment

Top comments (0)