CyberBytes Daily

Trending cyberattacks, explained simply.

supply chain attacks

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.

ATTACKER ACTIONS ACROSS THREE REGISTRIES📦1Create plausible package namesCrypto, DeFi, AI tooling themes🚀2Publish to npm, PyPI, Crates.io34 packages, 384+ versions, May 19-24🪝3Embed ecosystem-specific hookspostinstall, __init__.py, build.rs🔗4Tie all paths to shared C2ddjidd564.github.io as payload hostSocket detected packages at a median of 5 minutes 27 seconds after publication, but the six-day window before public disclosure allowed installations to occur.

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.

EXECUTION ON DEVELOPER WORKSTATION1Hook fires automaticallyNo user action beyond install/import🔍2Scan filesystem for credentialsSSH keys, AWS, GitHub, wallets, env vars3Validate stolen credentials liveAPI calls to AWS and GitHub📤4Encrypt and exfiltrateFernet/ECDH for npm, XOR for Rust🔒5Establish multi-vector persistencesystemd, cron, Git hooks, SSH keysThe PyPI packages fetched their payload remotely on each import, meaning the malicious logic was never present in the package itself.

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.

AI ASSISTANT POISONING VECTOR📝1Plant .cursorrules / CLAUDE.mdHidden instructions via zero-width Unicode🤖2Developer opens AI coding assistantCursor or Claude Code reads project files🎭3AI runs fake security scanAppears routine, exfiltrates secretsPARALLEL: PR-BASED SCALING ATTEMPT🔀PRs to 6 AI reposLangChain, LangFlow, LlamaIndex, MetaGPT, OpenHands, browser-use🛑All 6 PRs closedNone merged before detectionA merged PR would have exposed every developer cloning those repositories, with no malicious package install required.

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.

POST-COMPROMISE EXPANSION🔑1Weaponize stolen SSH keysAutomated lateral movement to connected systems🏗️2Reach CI/CD pipelinesPrivate repos, deployment infrastructure🌐3Exfiltrate via GitHub servicesPages, Gists, webhook.site as coverRouting through GitHub blended malicious traffic into normal developer activity, making network-level detection unreliable.

What Made This Possible

  1. 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 .cursorrules or CLAUDE.md file was written by legitimate maintainers or planted by a malicious install script.

  2. 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.

  3. 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 .cursorrules file 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.

TECHNICAL EXECUTION PATH BY ECOSYSTEM📦1npm: postinstall fires trap-core.jsHarvest, validate, persist, plant AI files🐍2PyPI: __init__.py fetches remote JSnode -e executes live payload from GitHub Pages⚙️3Crates.io: build.rs fires at compileXOR-encrypt wallets, exfil to GitHub Gists🤖4AI files parsed by Cursor/Claude CodeZero-width Unicode directives executed silently📡5All paths exfil via GitHub servicesBlends into normal developer trafficNo CVE applies. Standard SCA tools return zero findings across all 34 packages.

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 IDATT&CK nameHow it appeared
T1195.001Supply Chain Compromise: Compromise Software Dependencies and Development Tools34 malicious packages published across npm, PyPI, and Crates.io impersonating legitimate developer utilities
T1059.007Command and Scripting Interpreter: JavaScripttrap-core.js executed via npm postinstall hooks and via node -e in PyPI packages
T1552.001Unsecured Credentials: Credentials in FilesFilesystem scan for SSH keys, AWS credentials, GitHub tokens, wallet keystores, environment variables
T1552.004Unsecured Credentials: Private KeysSSH private keys harvested and used for lateral movement; blockchain wallet keystores exfiltrated
T1098.004Account Manipulation: SSH Authorized KeysModification of ~/.ssh/authorized_keys to enable persistent attacker SSH access
T1053.003Scheduled Task/Job: CronCron jobs established as one of multiple persistence mechanisms
T1543.001Create or Modify System Process: Launch Agentsystemd user services created for persistence
T1027.015Obfuscate Files or Information: SteganographyZero-width Unicode characters used to hide malicious instructions in AI assistant configuration files
T1071.001Application Layer Protocol: Web ProtocolsExfiltration and C2 via GitHub Pages, GitHub Gists, and webhook.site to blend with normal developer traffic
T1021.004Remote Services: SSHStolen 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.site endpoints (fallback exfiltration)

Filesystem Indicators

  • Unexpected .cursorrules or CLAUDE.md files 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 ~/.bashrc or ~/.zshrc not 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