CrowdSec — a company whose entire business is collaborative threat intelligence and intrusion prevention — has confirmed that attackers stole its source code, and attributes the breach to the May 2026 TanStack supply chain attack. If a security vendor with mature practices can be breached through a poisoned JavaScript dependency chain, your organization can be too. Every enterprise running Node.js builds, npm-based CI/CD pipelines, or developer workstations pulling from public registries should treat this as an active threat hunting trigger, not an interesting headline.
This incident is a textbook example of why supply chain compromise is now the highest-leverage attack path into otherwise well-defended networks: the attacker never touches your perimeter. They ride in through code your own developers voluntarily execute.
What Happened
Per the reporting from SecurityWeek, CrowdSec determined that its data breach — which resulted in theft of proprietary source code — traces back to the TanStack supply chain attack of May 2026. TanStack maintains some of the most widely consumed libraries in the JavaScript ecosystem (TanStack Query, Router, Table, and related tooling), which means a compromise of that ecosystem propagates transitively into thousands of downstream projects and corporate build pipelines.
The pattern here matches the modern npm supply chain playbook:
- Initial compromise of the upstream package or maintainer infrastructure — typically via stolen maintainer credentials, compromised publishing tokens, or malicious pull requests.
- Poisoned package versions published to the registry, often carrying malicious
preinstall/postinstalllifecycle scripts or obfuscated payloads embedded in otherwise legitimate library code. - Execution inside victim environments during routine
npm install/npm ci— on developer laptops, build agents, and CI runners, all of which typically hold high-value secrets: registry tokens, cloud credentials, SSH keys, signing keys, and repository access. - Credential harvesting and lateral movement — the harvested CI/CD and version control credentials are then used to access private source repositories, exactly as appears to have happened at CrowdSec.
The stolen asset — source code — is significant. Source code theft enables downstream vulnerability discovery against the victim's products, intellectual property loss, and, in the case of a security vendor, insight into detection logic that adversaries can work to evade.
Technical Analysis: How npm Supply Chain Compromise Works From a Defender's View
Affected component: The JavaScript/TypeScript dependency chain rooted in the TanStack package ecosystem, consumed via npm (and compatible registries). Any environment that installed or updated affected TanStack packages during the May 2026 exposure window is in scope: developer workstations, CI/CD runners (GitHub Actions, GitLab CI, Jenkins, Azure DevOps), container build pipelines, and artifact build systems.
No CVE has been published for this campaign. That is normal for supply chain incidents — the compromise is a malicious package version, not a software flaw. Do not wait for a CVE to act.
Attack chain observable behaviors:
npm/nodeprocesses spawning shell interpreters (sh,bash,cmd.exe,powershell.exe) via lifecycle scripts — legitimate builds rarely do this outside of known build tooling.- Obfuscated JavaScript (
eval,Function(,atob(, large base64 blobs) insidenode_modulesor install scripts. - Outbound network connections from
node/npmto non-registry destinations — credential exfiltration endpoints, paste sites, or attacker C2 — during or immediately after package installation. - Reads of sensitive credential material:
~/.npmrc,~/.ssh/,~/.aws/credentials,~/.config/gh/, environment variables containingTOKEN,SECRET, orKEY(CI runners expose these to every build step). - Persistence via modification of shell profiles, git hooks, or CI workflow files (
.github/workflows/*.yml).
Exploitation status: Confirmed in-the-wild compromise with at least one publicly disclosed victim (CrowdSec). Assume other victims exist — the defining characteristic of supply chain attacks is delayed discovery. CrowdSec's disclosure is likely the first of several.
Detection & Response
The detections below target the behavioral pattern of malicious npm lifecycle scripts and post-compromise credential theft — not package hashes, which change with every malicious release and will be stale within days. These are written to be low-noise: spawning shells from node and touching credential stores from build processes are not normal in disciplined environments.
SIGMA Rules
---
title: NPM or Node Process Spawning Shell Interpreter
description: Detects npm, npx, or node spawning shell interpreters, consistent with malicious package lifecycle scripts (preinstall/postinstall) observed in npm supply chain compromises such as the May 2026 TanStack attack.
id: 3b8f2a1c-7d44-4e91-b6c2-9a0e5f1d8c37
status: experimental
references:
- https://www.securityweek.com/crowdsec-confirms-source-code-stolen-in-supply-chain-attack/
- https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
date: 2026/06/10
tags:
- attack.initial_access
- attack.t1195.002
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\npm.cmd'
- '\npm.exe'
- '\node.exe'
- '\npx.cmd'
- '\yarn.cmd'
- '\pnpm.exe'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\mshta.exe'
- '\curl.exe'
- '\certutil.exe'
condition: selection_parent and selection_child
falsepositives:
- Legitimate build tooling (node-gyp, electron-builder) may spawn shells during native compilation; baseline per build host.
level: high
---
title: Suspicious Obfuscated or Network Activity in Node Install Scripts
description: Detects obfuscation primitives and inline download cradles in command lines executed under node/npm, a hallmark of poisoned npm package install scripts used in supply chain attacks.
id: 61c4d7e2-3a58-4f0b-9d21-8b6e4a2c7f09
status: experimental
references:
- https://www.securityweek.com/crowdsec-confirms-source-code-stolen-in-supply-chain-attack/
- https://attack.mitre.org/techniques/T1027/
author: Security Arsenal
date: 2026/06/10
tags:
- attack.defense_evasion
- attack.t1027
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/npm'
- '/node'
- '/npx'
- '/yarn'
- '/pnpm'
selection_cli:
CommandLine|contains:
- 'eval('
- 'atob('
- 'Function('
- 'base64 -d'
- 'curl http'
- 'wget http'
- '/dev/tcp/'
condition: selection_parent and selection_cli
falsepositives:
- Rare; minified build scripts sometimes use eval but should not appear in install-time child processes.
level: high
KQL Hunt (Microsoft Sentinel / Defender)
This query hunts for node/npm process trees touching credential material or making unexpected outbound connections — the exact behaviors required to turn a poisoned package into a source code theft, as seen at CrowdSec.
// Hunt: npm/node spawning shells or accessing credential stores (supply chain compromise pattern)
let SuspiciousChildren = dynamic(["cmd.exe", "powershell.exe", "pwsh.exe", "sh", "bash", "curl", "wget", "mshta.exe", "wscript.exe"]);
let CredentialPaths = dynamic([".npmrc", ".ssh", "credentials", ".aws", "gh/hosts.yml", "git-credentials", "TOKEN", "SECRET"]);
DeviceProcessEvents
| where TimeGenerated > ago(45d)
| where InitiatingProcessFileName in~ ("node.exe", "node", "npm", "npm.cmd", "npx", "yarn", "pnpm")
or InitiatingProcessCommandLine has_any ("npm install", "npm ci", "yarn add", "pnpm install")
| where FileName in~ (SuspiciousChildren)
or ProcessCommandLine has_any (CredentialPaths)
or ProcessCommandLine has_any ("eval(", "atob(", "base64", "Invoke-WebRequest", "curl http")
| project TimeGenerated, DeviceName, AccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, SHA256
| order by TimeGenerated desc;
For network-level hunting on CI runners and developer hosts (via Syslog/CEF ingestion for Linux build agents):
// Hunt: outbound connections from node/npm to non-registry destinations during install windows
CommonSecurityLog
| where TimeGenerated > ago(45d)
| where SourceProcessName has_any ("node", "npm", "npx", "yarn", "pnpm")
| where DestinationHostName !has_any ("registry.npmjs.org", "registry.yarnpkg.com", "npmjs.com", "github.com", "githubusercontent.com")
and not(ipv4_is_private(DestinationIP))
| summarize ConnectionCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
by SourceHostName, DestinationHostName, DestinationIP, DestinationPort
| order by ConnectionCount asc; // low-and-slow exfil surfaces first
Velociraptor VQL
Use this artifact across developer workstations and Linux build agents to enumerate node-spawned processes and recently modified npm credential/config artifacts during the exposure window.
-- Hunt for shells spawned by node/npm and recently touched credential files
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE CommandLine =~ '(npm|node|npx|yarn|pnpm)'
OR Exe =~ '(sh|bash|cmd\.exe|powershell\.exe)$'
-- Separately: enumerate npm credential/config files modified in the exposure window
SELECT FullPath, Mtime, Size
FROM glob(globs=['/home/*/.npmrc', '/root/.npmrc', '/home/*/.ssh/*', '/home/*/.aws/credentials'])
WHERE Mtime > '2026-05-01'
Remediation Script
Run this on build agents and developer Linux/macOS systems to audit for the exposure window and harvest indicators of compromise. It checks install history, scans node_modules for obfuscation patterns, and inventories outbound-connection-capable lifecycle scripts.
#!/bin/bash
# npm supply chain compromise audit — TanStack incident (May 2026)
# Run on CI runners, build agents, and developer workstations.
EXPOSURE_START="2026-05-01"
REPORT="npm_supply_chain_audit_$(hostname)_$(date +%Y%m%d).txt"
echo "=== npm Supply Chain Compromise Audit ===" > "$REPORT"
echo "Host: $(hostname) | Date: $(date)" >> "$REPORT"
# 1. Find all package-lock.json / yarn.lock / pnpm-lock.yaml referencing TanStack packages
echo -e "\n[1] TanStack dependency references in lockfiles:" >> "$REPORT"
find /home /root /opt /srv /var/lib -maxdepth 6 \( -name 'package-lock.json' -o -name 'yarn.lock' -o -name 'pnpm-lock.yaml' \) 2>/dev/null \
-exec grep -l '@tanstack' {} \; >> "$REPORT"
# 2. Scan node_modules install scripts for obfuscation and network cradles
echo -e "\n[2] Suspicious patterns in node_modules scripts:" >> "$REPORT"
find /home /root /opt /srv -maxdepth 7 -type d -name 'node_modules' 2>/dev/null | while read -r nm; do
grep -rEl 'eval\(|atob\(|Function\(|child_process|/dev/tcp/' "$nm" --include='*.js' 2>/dev/null \
| grep -E '(install|postinstall|preinstall)' >> "$REPORT"
done
# 3. Check npm logs for installs during the exposure window
echo -e "\n[3] npm debug logs with install activity since $EXPOSURE_START:" >> "$REPORT"
find /home /root -path '*/.npm/_logs/*' -newermt "$EXPOSURE_START" 2>/dev/null >> "$REPORT"
# 4. Credential file exposure check — files readable that shouldn't have been touched
echo -e "\n[4] Credential artifacts modified since exposure window:" >> "$REPORT"
find /home /root -maxdepth 3 \( -name '.npmrc' -o -name 'credentials' -o -name 'id_rsa*' -o -name 'hosts.yml' \) \
-newermt "$EXPOSURE_START" 2>/dev/null -exec ls -la {} \; >> "$REPORT"
# 5. Persistence check — modified git hooks and shell profiles
echo -e "\n[5] Persistence artifacts (hooks/profiles) modified since exposure window:" >> "$REPORT"
find /home /root /opt /srv -path '*/.git/hooks/*' -newermt "$EXPOSURE_START" 2>/dev/null >> "$REPORT"
find /home /root -maxdepth 2 \( -name '.bashrc' -o -name '.bash_profile' -o -name '.zshrc' -o -name '.profile' \) \
-newermt "$EXPOSURE_START" 2>/dev/null >> "$REPORT"
echo -e "\nAudit complete. Review $REPORT and escalate any hits to IR immediately."
Remediation and Hardening Guidance
If you consumed TanStack packages during May 2026, assume exposure until proven otherwise:
- Rotate credentials that existed in build environments during the exposure window. This is the highest-priority action. npm tokens, GitHub/GitLab PATs and deploy keys, cloud IAM keys, SSH keys, and any secrets injected as CI environment variables should be considered compromised. CrowdSec's attackers moved from package compromise to source repository access — that pivot only works with stolen credentials.
- Pin and verify dependencies. Audit every
package-lock.jsonagainst the affected package versions listed in the upstream TanStack/maintainer disclosure. Remove affected versions entirely — do not simply upgrade and move on; confirm no build artifact produced during the window shipped to production. - Review repository access logs. Pull git hosting audit logs (GitHub audit log, GitLab events API) for the exposure window and look for clone/fetch activity from unrecognized IPs, new deploy keys, unexpected OAuth grants, and workflow file modifications. Source code theft leaves traces in VCS telemetry.
- Disable lifecycle scripts in CI where feasible. Run installs with
npm ci --ignore-scriptsfor dependencies that do not require native builds. This single control neuters the most common npm malware execution path. - Segment CI/CD blast radius. Build runners should be ephemeral, hold short-lived scoped credentials (OIDC-based federation instead of static tokens), and have no standing access to production source or artifact systems beyond what the job requires.
- Egress filtering on build agents. Node processes in CI have no business talking to arbitrary internet endpoints. Allowlist the npm registry and required artifact hosts; alert on everything else.
- Deploy registry proxying with malware scanning. Route all package installs through an internal proxy (Artifactory, Nexus, or equivalent) with package scanning and version-age policies — e.g., block packages published less than 7 days ago unless explicitly approved. Most supply chain victims are hit in the first hours after a malicious publish.
Monitor CrowdSec's official communications and the TanStack maintainers' disclosure channels for the definitive list of affected package versions, and cross-reference CISA advisories as they are published.
Executive Takeaways
Supply chain compromise through a ubiquitous JavaScript ecosystem is not a development problem — it is an enterprise risk problem. The CrowdSec breach demonstrates that attackers are deliberately targeting dependency chains to harvest CI/CD credentials and pivot into source repositories. Organizations that cannot answer "which of our build agents installed TanStack packages in May 2026, and what credentials did those agents hold?" have a visibility gap that needs closing this quarter, not next year.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.