DEV Community

Pico
Pico

Posted on Edited on Originally published at getcommit.dev

I Scored the TrapDoor Packages. The 21 Still Standing All Scored 15-18.

On May 22, a cluster of accounts published 34 packages across npm, PyPI, and Crates.io. 384 versions total, all in waves within hours.

The credential theft was standard. The part that wasn't: poisoned .cursorrules and CLAUDE.md files containing zero-width Unicode characters. Invisible to text editors. Readable by AI assistants. The hidden instructions told your coding assistant to run a "security scan" that harvested your SSH keys, cloud credentials, and wallet data.

Three registries at once

Each ecosystem got its own execution vector:

  • npm (21 packages): postinstall hooks
  • PyPI (7 packages): auto-execute on import
  • Crates.io (6 packages): build.rs scripts

The names were engineered for AI suggestion: llm-context-compressor, prompt-engineering-toolkit, wallet-security-checker, defi-risk-scanner. Ask an AI assistant for a prompt management library and it might suggest one of these.

What behavioral scoring says

I ran every TrapDoor package through Commit's audit:

Package Ecosystem Score Downloads Age
llm-context-compressor npm 15 42/wk <1yr
prompt-engineering-toolkit npm 15 35/wk <1yr
model-switch-router npm 15 42/wk <1yr
workspace-config-loader npm 15 21/wk <1yr
cryptowallet-safety PyPI null 0/wk <1yr
defi-risk-scanner PyPI null 0/wk <1yr

Every package: 15 to 18, or null. No longevity. No community. No release history. No GitHub repo.

A word on the nulls, because they matter. Those packages were already pulled when I scanned, so there is no registry record left to score. A null is not a clean bill and it is not a 15 either. It is an absence. Of the 34, I scored 21 — the npm ones, which survived as security-holder stubs with their publish-time metadata intact. The other 13 I am reasoning about from the campaign fingerprint, not from a score I ran.

A behavioral gate set to block HIGH-risk packages would have stopped every one I can still score, on first install. No CVE lookup. No signature matching. For the 13 already pulled, that claim rests on the shared publisher fingerprint rather than on a measurement — which is worth saying out loud, given that the whole argument here is that the record is the thing you should trust.

The AI poisoning angle

This is the threat model shift. Traditional supply chain malware runs in postinstall. TrapDoor's secondary payload runs when your AI assistant reads a file.

The zero-width Unicode instructions direct the assistant to scan for git credentials, VS Code settings, environment variables, and SSH keys. Exfiltration goes through raw.githubusercontent.com and GitHub Pages. Your firewall allows those domains.

Your AI assistant does what the hidden text says because it processes every character in its context window, including the ones you can't see.

What to do

Gate your AI's package installs:

npx proof-of-commitment hook
Enter fullscreen mode Exit fullscreen mode

This intercepts every npm install, pip install, cargo add, and go get from Cursor and Claude Code. Packages below the threshold get blocked before they hit your machine.

For stricter blocking (recommended for crypto/AI teams):

COMMIT_HOOK_SEVERITY_BLOCK=HIGH npx proof-of-commitment hook
Enter fullscreen mode Exit fullscreen mode

Check for poisoned config files:

grep -rP '[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{2060}]' .cursorrules CLAUDE.md **/*.mdc 2>/dev/null
Enter fullscreen mode Exit fullscreen mode

Audit what's already installed:

npx proof-of-commitment --file package-lock.json
Enter fullscreen mode Exit fullscreen mode

TrapDoor is the fifth major supply chain attack in three months. LiteLLM, axios, Shai-Hulud, Miasma, now this. Each one escalates. The entry point keeps changing. The pattern doesn't: packages with zero behavioral history get installed because nothing checks.

Top comments (0)