Listen to this Post

Introduction:
A new wave of stealthy supply chain attacks has been discovered, with the TrapDoor campaign compromising 34 malicious packages and over 384 related versions across npm, PyPI, and Rust’s Crates.io. This operation uses distinct, ecosystem-specific execution paths to steal developer credentials and cryptocurrency wallets. It specifically targets developers in the crypto, DeFi, Solana, and AI communities by disguising malware as generic developer tools and security scanners.
Learning Objectives:
- Analyze how attackers exploit OIDC tokens and cache poisoning to publish authenticated malicious packages.
- Implement detection commands for identifying compromised dependencies across Python, JavaScript, and Rust ecosystems.
- Apply mitigation workflows using tools like
pip-audit,cargo audit, and CI/CD scanning to block worm propagation.
You Should Know:
- Exploit Chain: OIDC Token Theft & Signed Worm Packages
The TrapDoor campaign weaponizes GitHub Actions vulnerabilities in a multi-stage attack. Attackers fork a legitimate repository (e.g., TanStack/router), open a pull request that triggers a `pull_request_target` workflow, and poison the GitHub Actions cache with a malicious payload. When a maintainer later merges a legitimate PR, the poisoned cache restores attacker-controlled binaries that extract OIDC tokens directly from the GitHub Actions runner memory via /proc/<pid>/mem.
These stolen OIDC tokens are then used to publish malicious package versions to npm without ever needing to steal long-lived credentials. Because the packages are published from a legitimate GitHub Actions runner using valid OIDC tokens, they carry valid npm provenance attestations (SLSA Build Level 3) and legitimate GitHub Actions signatures. This means provenance alone is not a reliable safety signal for this attack.
Detection & Forensics Commands (Linux/macOS)
1. Check for suspicious GitHub Actions cache entries
gh cache list --repo <owner/repo> --json id,key,size,lastModifiedAt | jq '.[] | select(.key | test("pnpm-store|node_modules"))'
<ol>
<li>Monitor runner process memory for OIDC token extraction attempts
Look for ptrace events or /proc/pid/mem access from CI runners
sudo ausearch -m ptrace -ts recent | grep "/proc/./mem"</p></li>
<li><p>Check npm provenance for any package installed in the last 48 hours
npm audit --json | jq '.advisories | to_entries[] | select(.value.severity=="critical" and .value.range=="")'</p></li>
<li><p>Verify Sigstore attestations locally (requires cosign)
cosign verify-attestation --type slsaprovenance --certificate-identity-regexp ".github.com/TanStack/router/." <package>@<version>
Windows Detection (PowerShell)
Check for anomalous GitHub Actions runner processes
Get-Process | Where-Object {$_.ProcessName -match "runner|actions"} | Get-Process -Module | Select-Object ProcessName, Modules
Examine npm global packages for recent malicious timestamps
Get-ChildItem "$env:APPDATA\npm\node_modules" | Where-Object {$<em>.LastWriteTime -gt (Get-Date).AddHours(-48)} | ForEach-Object { npm view $</em>.Name versions --json | ConvertFrom-Json }
- Worm Propagation: How a Single Install Eats Your Secrets
Once a developer installs any affected package version, the malicious payload executes during standard npm lifecycle hooks (preinstall, postinstall). It steals GitHub tokens, npm tokens, AWS credentials (via IMDSv2), GCP and Azure credentials, Kubernetes service account tokens, HashiCorp Vault tokens, environment variables, and cryptocurrency wallet data.
The worm then identifies npm packages the victim has publish access to, modifies those package archives to inject the same malicious dependency, bumps versions, and publishes new compromised releases using the stolen credentials. This worm behavior means each compromised developer or CI runner becomes a new infection vector, amplifying the attack across the ecosystem.
Isolation & Scanning Tutorial
Step 1: Isolate the environment
For Python - create a sandboxed virtual environment python3 -m venv /tmp/venv-sandbox source /tmp/venv-sandbox/bin/activate For Node.js - use Docker for true isolation docker run -it --rm -v $(pwd):/app node:18-alpine sh -c "cd /app && npm install --no-package-lock"
Step 2: Scan all dependencies for known malicious versions
Python (PyPI):
Install chaincanary - detects supply chain attacks before they execute pip install chaincanary chaincanary audit -r requirements.txt --deep-scan Use pip-audit against the Python Advisory Database pip install pip-audit pip-audit --requirement requirements.txt --desc --verbose
Node.js (npm):
Comprehensive audit with reachability analysis npm audit --production --json > audit-report.json npm audit fix --dry-run --force Use pkg-audit-fix for cross-package manager scanning npx pkg-audit-fix@latest scan --depth=5
Rust (Crates.io):
Install cargo audit (RustSec DB) cargo install cargo-audit cargo audit --deny warnings --json Use cargo-crev for cryptographic code review verification cargo install cargo-crev cargo crev verify --recursive cargo crev repo fetch all cargo crev id trust --level high <reviewer-id>
Step 3: Block known malicious domains at the network level
Append to /etc/hosts (Linux/macOS) or C:\Windows\System32\drivers\etc\hosts (Windows) echo "0.0.0.0 filev2.getsession.org" | sudo tee -a /etc/hosts echo "0.0.0.0 api.github.com/user/repos" | sudo tee -a /etc/hosts echo "0.0.0.0 gh-token-monitor" | sudo tee -a /etc/hosts Or use iptables (Linux) sudo iptables -A OUTPUT -d filev2.getsession.org -j DROP sudo iptables -A OUTPUT -d 45.79.96.0/24 -j DROP Session/Oxen nodes range
- The Wiper Daemon: Revoke Tokens, Lose Your Home Directory
The most destructive component is gh-token-monitor, a persistent daemon that polls GitHub every 60 seconds. If it detects token revocation, it immediately executes rm -rf ~/, wiping the user’s home directory. On Linux, it persists via systemd user services; on macOS, via LaunchAgent plist; on Windows, via scheduled tasks.
Eradication Steps (Must Follow Before Revoking Tokens)
1. Linux: Locate and stop the malicious systemd service
systemctl --user list-units | grep -E "gh-token-monitor|pgsql-monitor"
systemctl --user stop gh-token-monitor.service
systemctl --user disable gh-token-monitor.service
find ~/.config/systemd/user -name "monitor" -type f -delete
<ol>
<li>macOS: Remove LaunchAgent persistence
launchctl list | grep -i monitor
launchctl unload ~/Library/LaunchAgents/com.gh-token-monitor.plist
rm -f ~/Library/LaunchAgents/com.gh-token-monitor.plist</p></li>
<li><p>Windows (PowerShell as Admin)
Get-ScheduledTask | Where-Object {$<em>.TaskName -like "monitor"} | Disable-ScheduledTask
Get-ScheduledTask | Where-Object {$</em>.TaskName -like "monitor"} | Unregister-ScheduledTask -Confirm:$false</p></li>
<li><p>Delete all persisted payload files across all OSes
find / -name "gh-token-monitor" -type f 2>/dev/null
find / -name "pgsql-monitor" -type f 2>/dev/null
After finding them, delete with: rm -f [full-path]
4. Ecosystem-Specific Execution Paths & Defense-in-Depth
The TrapDoor campaign uses distinct, ecosystem-specific execution paths:
| Ecosystem | Attack Vector | Malicious Packages Count | Defensive Tool |
|–|–|-|-|
| npm | preinstall/postinstall scripts + OIDC theft | 373 versions across 169 names | `npm audit` + `@socketsecurity/cli` |
| PyPI | `setup.py` hooks + dynamic imports | 2 packages (spreading) | `pip-audit` + `chaincanary` |
| Crates.io | `build.rs` scripts + proc macros | Active investigation | `cargo audit` + `cargo crev` |
Hardening Package Managers
npm: Disable lifecycle scripts globally (blocks preinstall/postinstall)
npm config set ignore-scripts true
For per-project: Add .npmrc with "ignore-scripts=true"
PyPI: Use pip in hash-checking mode
pip install --require-hashes -r requirements.txt
Generate hash-protected requirements:
pip freeze | sed 's/==/ @ /' | xargs -I {} pip download --no-deps {} | grep -oP 'SHA256:\K.' >> requirements.txt
Crates.io: Verify using cargo-vet for audited dependencies
cargo install cargo-vet
cargo vet init
cargo vet certify <crate> --version <ver> --user-id <your-github>
- CI/CD Compromise Recovery: The Full Incident Response Workflow
If you suspect a TrapDoor compromise in your CI/CD pipeline, follow this verified IR workflow:
PHASE 1: Stop the bleeding (execute immediately)
Rotate all tokens BEFORE running any other commands that could trigger the wiper
Create new tokens via: GitHub Settings > Developer settings > Personal access tokens
PHASE 2: Scan and inventory every runner and local environment
Parallel scanning across all projects (adjust -P to core count)
find . -name "package.json" -or -name "requirements.txt" -or -name "Cargo.toml" | parallel -P 4 "npm audit --prefix {//} --json > {//}/audit-{/.}.json"
PHASE 3: Isolate infected runners and rebuild from clean snapshots
Do NOT just clean - rebuild entirely
For GitHub Actions:
1. Disable the runner: Settings > Actions > Runners > Remove
2. Delete the runner VM/image snapshot completely
3. Provision a fresh runner from a golden image without any persisted caches
PHASE 4: Validate all npm package provenance before allowing new installs
npm audit signatures Verify all installed package signatures against registry
For any package without valid signature, treat as compromised
- AI & Crypto Developer Protection: Exposing TrapDoor’s Primary Target
The campaign explicitly targets developers in the crypto, DeFi, Solana, and AI communities. Attackers know AI developers often push code faster than security scans can run, and crypto developers store seed phrases and wallet keys in environment variables or local files.
AI Supply Chain Hardening
Scan all HuggingFace model dependencies for backdoored transformers pip list --format=freeze | grep -E "torch|transformers|tensorflow|jax" >> ~/ai-audit.log Compare against known vulnerable versions from PyPI advisory DB pip-audit --requirement <(pip freeze) --desc --vulnerable-only --fix Monitor model loading for unauthorized network requests (MITM proxy) mitmproxy --mode transparent --listen-port 8080 --set block_global=false & export HTTP_PROXY=http://localhost:8080 export HTTPS_PROXY=http://localhost:8080 python run_ai_model.py Monitor for any outbound exfiltration attempts
Crypto Wallet Protection
1. Never store mnemonics in environment variables - use hardware security modules 2. Monitor for wallet file access attempts using auditd sudo auditctl -w ~/.config/solana/id.json -p rwa -k solana-wallet sudo auditctl -w ~/.ethereum/keystore -p rwa -k eth-wallet Check logs: ausearch -k solana-wallet <ol> <li>Use GitGuardian or truffleHog to scan for accidentally committed secrets trufflehog filesystem --only-verified --directory . --exclude-paths .gitignore
What Undercode Say:
- Attackers rely on trust in signed packages: The TrapDoor campaign proves that SLSA provenance and Sigstore attestations are not sufficient defense when the build pipeline itself is compromised. Organizations must implement behavior-based runtime detection, not just static verification.
- The wiper daemon changes IR procedures: Deleting a user’s home directory on token revocation creates a chilling effect—security teams must locate and kill the persistence mechanisms before initiating any token revocation, or risk catastrophic data loss. This is a significant shift from standard incident response playbooks.
Prediction:
Supply chain attacks will escalate to target AI model registries (HuggingFace, Replicate) and crypto package managers by late 2026, using similar OIDC token theft from CI/CD runners. We predict the emergence of AI-powered automated package poisoning—where LLMs are used to dynamically generate malicious packages that pass basic security scans. Organizations without runtime dependency behavior monitoring will face mandatory breach disclosures. Immediate adoption of zero-trust package management (cryptographic provenance + behavioral analysis + real-time network egress filtering) is no longer optional—it’s survival.
▶️ Related Video (80% Match):
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Cybersecuritynews Supplychainattack – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


