How attackers turned AI coding assistants into silent credential thieves across three package registries
Your AI coding assistant reads every file in your project directory, including hidden configuration files you never wrote. In the TrapDoor campaign, discovered on May 24, 2026, attackers exploited that behavior by planting configuration files containing invisible instructions, written in zero-width Unicode characters that no text editor or code review tool would display, but that AI tools like Cursor and Claude Code parse and act on. When a developer opened a poisoned project, their AI assistant ran what looked like a routine security scan and silently sent their credentials to the attacker.
That technique was the second stage of a larger operation. The first stage was a coordinated wave of 34 malicious packages published across npm, PyPI, and Crates.io between May 19 and May 24, 2026, targeting developers in the crypto, DeFi, and AI tooling communities. Each package was engineered to fire automatically the moment a developer installed or imported it, with no further action required. The packages harvested SSH keys, AWS credentials, GitHub tokens, and blockchain wallet keystores, then validated the stolen credentials against live APIs to identify which ones were still active.
The detail that should concern any security leader: the attacker also submitted pull requests to six major open-source AI projects, including LangChain, LangFlow, and LlamaIndex, each framed as a routine documentation improvement. Had any of those pull requests merged, every developer who subsequently cloned those repositories and used a compatible AI coding assistant would have been exposed, with no malicious package installation required. None merged. But the attempt demonstrates that the attack surface now includes the AI tools sitting inside developer environments, not just the packages those developers install.
Narrative · 7 min read
The Context
Software developers rarely install packages manually one at a time. They declare dependencies in a project file and let a package manager handle the rest. The npm registry serves JavaScript developers, PyPI serves Python developers, and Crates.io serves Rust developers. Together, these three registries host millions of packages and process billions of downloads per year.
The crypto and AI development communities are particularly active on these registries. A developer building a DeFi application or an AI agent framework might install dozens of packages in a single session, many of them small utilities with names that sound like plausible tools. That familiarity is what TrapDoor exploited.
The Attack, Phase by Phase
Phase 1: Registry Seeding
Beginning May 19, 2026, the attacker published packages in coordinated waves across all three registries. Package names were chosen to sound like plausible developer utilities: prompt-engineering-toolkit, solidity-deploy-guard, defi-threat-scanner, sui-move-build-helper. The naming strategy targeted developers who would find these names unremarkable.
Each registry received a tailored execution hook. npm packages used postinstall scripts. Python packages executed malicious code at import time via __init__.py. Rust packages used build.rs scripts that fire during compilation. All three attack paths shared the same command-and-control infrastructure anchored to the GitHub account ddjidd564.
Phase 2: Credential Harvest and Persistence
The moment a developer installed an npm package, the postinstall hook fired a 1,149-line JavaScript payload called trap-core.js. This script scanned the local filesystem for SSH keys, AWS credentials, GitHub tokens, browser login databases, crypto wallet extension data, and API keys. It then made live API calls to AWS and GitHub to test which stolen credentials were still active, filtering for high-value targets before exfiltrating anything.
The PyPI packages used a different architecture. Rather than bundling the malicious payload, they fetched a fresh JavaScript file from the attacker's GitHub Pages domain on every import and executed it using node -e. This remote-payload design meant a static scan of the PyPI package itself would find almost nothing suspicious, and the attacker could update malicious behavior in real time without publishing a new release.
The Crates.io packages targeted Rust developers building on the Sui and Aptos blockchain platforms. Their build.rs scripts searched for local wallet keystores, encrypted them using a hardcoded XOR key, and sent them to GitHub Gists. Most dependency analysis tools do not inspect Rust build scripts for outbound network activity, making this exfiltration path invisible to standard tooling.
The npm payload also established persistence through multiple simultaneous mechanisms: systemd user services, cron jobs, Git pre-push hooks, shell configuration file modifications, and additions to ~/.ssh/authorized_keys.
Phase 3: AI Assistant Poisoning
The trap-core.js payload also planted .cursorrules and CLAUDE.md files in developer project directories. These files contained hidden instructions written using zero-width Unicode characters—U+200B, U+200C, U+200D, and U+FEFF—that are completely invisible in standard editors and code review diffs. AI coding tools like Cursor and Claude Code parse the full Unicode stream and act on whatever instructions those characters encode.
When a developer with a poisoned project opened their AI assistant, the assistant was directed to run what appeared to be a routine security scan. The scan silently discovered and exfiltrated local secrets.
To scale this vector further, the attacker used the ddjidd564 GitHub account to submit pull requests to six major open-source AI projects: LangChain, LangFlow, LlamaIndex, MetaGPT, OpenHands, and browser-use. Each PR was titled "docs: add .cursorrules with dev standards and build verification," framing a poisoned configuration file as a benign documentation improvement. Had any merged, every developer who cloned those repositories and used a compatible AI coding assistant would have been exposed with no package installation required. All six were identified and closed without merging.
Phase 4: Lateral Movement and Infrastructure Abuse
Stolen SSH keys were used for automated lateral movement to connected systems, potentially reaching CI/CD pipelines, private repositories, and downstream deployment infrastructure. The attacker routed all command-and-control traffic through legitimate developer services: GitHub Pages for payload hosting, GitHub Gists for receiving stolen data, and webhook.site as a fallback receiver. This blended malicious traffic into the enormous volume of legitimate GitHub API calls that most enterprise networks generate daily.
The attacker's GitHub Pages repository also hosted an operational document describing the campaign as a "Universal AI Agent Extraction Framework" with staged workflows for capability detection, data extraction, self-replication, and telemetry reporting. The campaign was designed as a reusable framework, not a one-time operation.
What Made This Possible
-
AI coding assistants have no file-origin verification. Tools like Cursor and Claude Code read every configuration file in a project directory and treat its contents as authoritative. There is no mechanism to verify whether a
.cursorrulesorCLAUDE.mdfile was written by legitimate maintainers or planted by a malicious install script. -
Standard security tooling is blind to malicious-by-design packages. SCA tools match package versions against CVE databases. TrapDoor packages carry no CVE because they are not vulnerable software—they are malicious software. Every CVE-feed scanner returns zero findings across all 34 packages.
-
Cross-registry operations outpace single-registry monitoring. The attacker simultaneously operated across npm, PyPI, and Crates.io with ecosystem-specific payloads. An organization monitoring only one registry would see only a fragment of the campaign.
What Should Have Stopped This
- Behavioral analysis at install time. Socket Security detected packages at a median of 5 minutes 27 seconds after publication by analyzing behavior rather than matching CVE databases. Behavioral scanning catches malicious-by-design packages that CVE feeds miss entirely.
- Restricted AI assistant file access. Configuring AI coding tools to read only explicitly approved file types, or to require confirmation before acting on project-level configuration files, would prevent a planted
.cursorrulesfile from being treated as authoritative. - Least-privilege credentials on developer workstations. If AWS credentials are scoped to only what a developer needs for local testing, a credential theft yields far less value. The same applies to GitHub tokens scoped to read-only access on a single repository.
- Pull request review policies for configuration files. The six PRs were framed as documentation improvements. A policy flagging any PR that adds or modifies AI assistant configuration files would have surfaced these for additional scrutiny before merge.
The Takeaway
TrapDoor is the same class of failure as the Axios supply chain attack: a trusted execution context was weaponized against the organization it was built to serve. The Axios attack exploited trust in the npm build process. TrapDoor exploited trust in the AI assistant's project context. The shared failure is a system that reads and acts on instructions without verifying their origin.
What makes TrapDoor structurally different is the target. Previous supply chain attacks aimed at production systems through the build pipeline. TrapDoor aimed at the developer workstation as a credential store worth more than the production environment it connects to. SSH keys, AWS credentials, and GitHub tokens on a single developer laptop can reach CI/CD pipelines, private repositories, and deployment infrastructure that no external attacker could otherwise access. Security programs have spent years hardening the pipeline. TrapDoor is a signal that the workstation running the pipeline is now the softer target.
Pattern to remember: When a tool reads and executes instructions from project files without verifying their origin, any process that can write to those files can control the tool.
What changed: AI coding assistants have introduced a new class of instruction-following agent inside the developer environment—one that existing security models treat as a passive editor rather than an active executor with local credential access.
Technical Deep Dive · 3 min
The Technical Mechanism
TrapDoor operated across three distinct execution layers, each exploiting the native automation hooks of its target ecosystem.
npm (21 packages): Packages used package.json postinstall hooks to execute trap-core.js (48,485 bytes, 1,149 lines) immediately upon installation. The payload performed filesystem credential harvesting, live credential validation via AWS STS GetCallerIdentity and GitHub /user API calls, Fernet and ECDH encryption of exfiltrated data, and multi-vector persistence establishment. Persistence mechanisms included systemd user services, cron jobs, Git pre-push hooks, shell RC file modifications (~/.bashrc, ~/.zshrc), and ~/.ssh/authorized_keys modification. The payload also planted .cursorrules and CLAUDE.md files containing hidden directives encoded in zero-width Unicode characters (U+200B, U+200C, U+200D, U+FEFF).
PyPI (7 packages): Packages executed malicious code at import time via __init__.py. Rather than bundling a payload, they fetched a remote JavaScript file from ddjidd564.github.io and executed it using node -e. This remote-payload architecture meant the malicious logic was absent from the package itself, defeating static analysis. The remote configuration URL ddjidd564.github.io/defi-security-best-practices/config.json is shared across both npm and PyPI samples, providing a strong code-level linkage between the two ecosystems per SlowMist's analysis.
Crates.io (6 packages): Packages abused build.rs scripts that execute automatically during cargo build, before any developer-authored code runs. These scripts searched for Sui and Aptos wallet keystores, encrypted them using a hardcoded XOR key (cargo-build-helper-2026), and exfiltrated them to GitHub Gists. SlowMist notes the Rust samples lack the remote configuration retrieval and propagation capabilities present in the npm and PyPI samples, representing a simpler, more targeted design.
AI assistant poisoning: The zero-width Unicode characters used in .cursorrules and CLAUDE.md files are fully valid Unicode and are parsed by AI text processing pipelines. The characters encode instructions that direct the AI assistant to execute a credential discovery and exfiltration routine framed as a security scan. This technique exploits the same prompt injection class of flaw as CWE-78 variants identified in Claude Code CLI by Phoenix Security in April 2026, delivered via supply chain rather than requiring direct repository access.
Campaign infrastructure: All C2 traffic routed through ddjidd564.github.io (payload hosting), GitHub Gists (data exfiltration), and webhook.site (fallback receivers). The consistent campaign marker P-2024-001 appears across all packages, pull requests, and payload configurations. The attacker-hosted repository contained AUDIT-MATRIX.md, BYPASS.md, PAYLOAD.md, and SWARM.md, describing a "Universal AI Agent Extraction Framework" with staged operational workflows.
CVE and Advisories
No CVE has been assigned to TrapDoor. The packages are malicious by design rather than vulnerable by flaw; they will not appear in CVE databases. CWE-506 (Embedded Malicious Code) applies across all 34 packages per CyberSec Sentinel's analysis.
SlowMist issued emergency security warning SM-2026-352284 on May 28, 2026.
MITRE ATT&CK Mapping
| Technique ID | ATT&CK name | How it appeared |
|---|---|---|
| T1195.001 | Supply Chain Compromise: Compromise Software Dependencies and Development Tools | 34 malicious packages published across npm, PyPI, and Crates.io impersonating legitimate developer utilities |
| T1059.007 | Command and Scripting Interpreter: JavaScript | trap-core.js executed via npm postinstall hooks and via node -e in PyPI packages |
| T1552.001 | Unsecured Credentials: Credentials in Files | Filesystem scan for SSH keys, AWS credentials, GitHub tokens, wallet keystores, environment variables |
| T1552.004 | Unsecured Credentials: Private Keys | SSH private keys harvested and used for lateral movement; blockchain wallet keystores exfiltrated |
| T1098.004 | Account Manipulation: SSH Authorized Keys | Modification of ~/.ssh/authorized_keys to enable persistent attacker SSH access |
| T1053.003 | Scheduled Task/Job: Cron | Cron jobs established as one of multiple persistence mechanisms |
| T1543.001 | Create or Modify System Process: Launch Agent | systemd user services created for persistence |
| T1027.015 | Obfuscate Files or Information: Steganography | Zero-width Unicode characters used to hide malicious instructions in AI assistant configuration files |
| T1071.001 | Application Layer Protocol: Web Protocols | Exfiltration and C2 via GitHub Pages, GitHub Gists, and webhook.site to blend with normal developer traffic |
| T1021.004 | Remote Services: SSH | Stolen SSH keys used for automated lateral movement to connected systems |
Indicators of Compromise
Publisher Accounts
- npm:
asdxzxc - PyPI:
asdmini67,dae5411 - GitHub:
ddjidd564
C2 and Payload Infrastructure
ddjidd564.github.io(payload hosting and remote configuration)ddjidd564.github.io/defi-security-best-practices/config.json(shared remote config URL)- GitHub Gists under account
ddjidd564(exfiltration destination) webhook.siteendpoints (fallback exfiltration)
Filesystem Indicators
- Unexpected
.cursorrulesorCLAUDE.mdfiles in project directories not created by the developer - Presence of
trap-core.js(48,485 bytes) in project or temp directories - Unexpected entries in
~/.ssh/authorized_keys - New systemd user services or cron jobs with no corresponding developer action
- Modifications to
~/.bashrcor~/.zshrcnot made by the developer
Campaign Marker
String P-2024-001 in package metadata, payload configurations, or pull request descriptions.
Detection Note
Because TrapDoor carries no CVE and packages are malicious by design, CVE-feed scanners and CVSS-based tools return zero findings. Detection requires behavioral analysis at install time (outbound network calls from postinstall scripts, filesystem access to credential paths) or registry-level behavioral scanning.
Attribution
Unattributed. No credible link to any previously named APT group or nation-state has been established. The campaign is operationally tied to GitHub account ddjidd564, npm publisher asdxzxc, and PyPI publishers asdmini67 and dae5411. The campaign marker P-2024-001 either represents an internal tracking convention or is a deliberate false flag referencing a 2024 date to mislead attribution, per the Cloud Security Alliance research note. Rescana assessed the actor as financially or strategically motivated based on targeting of cryptocurrency assets, cloud infrastructure credentials, and sensitive codebases. Multiple analysts characterized the operation as the work of a well-resourced team based on the ecosystem-specific payload design, live credential validation, remote payload architecture, and AI assistant poisoning capability.
Primary Sources
- 01.TrapDoor Crypto Stealer Supply Chain Attack Hits 34 Packages Across npm, PyPI, and Crates.io
Socket Security · May 24, 2026
- 02.Threat Intelligence: TrapDoor Analysis, A Cross-Ecosystem Supply Chain Credential Theft Operation
SlowMist (via Medium) · May 28, 2026
- 03.TrapDoor Supply Chain Attack Spreads Credential-Stealing Malware via npm, PyPI, and CratesIO
The Hacker News · May 25, 2026
- 04.TrapDoor: Supply Chain Attack Poisons AI Coding Assistants
Cloud Security Alliance Labs · May 26, 2026
- 05.TrapDoor Supply Chain Campaign: Cross-Ecosystem Credential Theft and AI Assistant Poisoning via npm, PyPI, and Crates.io
Phoenix Security · May 25, 2026
- 06.TrapDoor Targets 34 Packages Across npm, PyPI and Crates.io to Steal Crypto Keys and Poison AI Assistants
CyberSec Sentinel · May 26, 2026