OpenAPI React Query Codegen Compromised in Mini Shai-Hulud npm Supply Chain Attack
Ten malicious versions of the npm package @7nohe/openapi-react-query-codegen were published with valid provenance attestations after a threat actor abused a comment-triggered GitHub Actions publishing workflow. The packages execute an obfuscated JavaScript loader during installation that decrypts a second-stage payload targeting cloud, package registry, and CI/CD credentials with self-propagation capabilities. The attack leverages legitimate infrastructure like GitHub for exfiltration and command retrieval, and establishes persistence via LaunchAgents, systemd services, and developer tool configuration modifications.
- filename3FWCvzduYZg.jsPrimary obfuscated JavaScript loader (~5.7MB) dropped by the malicious npm package and executed during installation
- filenameai_init.jsSecondary payload entry script executed by the Bun runtime after being downloaded by the loader
- filenameai_setup.shScript copied to remote hosts via SSH for propagation
- filenamebinding.gypMalicious native-build manifest using Python escapes to trigger the loader via os.system() during npm install
- filename.config/index.jsPayload copy injected into developer tool configuration directories for persistence
- filename~/.config/systemd/user/sysvinit-detect-fash.serviceLinux systemd user service persistence mechanism for the token monitor
- filename~/.config/sysvinit-detect-fash/fash-detectedToken monitor handler file containing executable shell code evaluated via eval
- filename~/.config/sysvinit-detect-fash/foxToken monitor configuration directory and file
- filename.github/_index.jsPayload injected into GitHub repositories via workflow poisoning to collect CI secrets
- filenameis_it_this_simple.jsScript executed in prerelease versions with environment variables for workflow and target package targeting
- filename~/Library/LaunchAgents/com.user.sysvinit-detect-fash.plistmacOS LaunchAgent persistence mechanism for the token monitor with RunAtLoad and KeepAlive set
- filename~/.local/bin/sysvinit-detect-fash.shToken monitor installer script path on Linux/macOS
- filename/var/tmp/.shitFile recording URL hashes of executed commands to prevent duplicate execution via the signed GitHub-commit command channel
- sha25659370c67b54a0ccaedd265e2356f04540b2fba1e1845300ef6de4d5437d99380Additional SHA256 hash of the primary malicious JavaScript loader 3FWCvzduYZg.js
- sha256b49afb7dba04cd99b357ce7c652c823a3707f28e130bd5c6645851a7adc030d6SHA256 hash of the primary malicious JavaScript loader 3FWCvzduYZg.js
- sha256d3246926b20a8d021ed7de0ac8e9eee1dda986088f84ba18f31cb2042a121f5dSHA256 hash of the malicious binding.gyp file used to trigger execution via node-gyp
- urlhxxps://github[.]com/p00paboot/openapi-react-query-codegenThreat actor's GitHub fork used to stage the malicious code before publishing
- urlhxxps://raw[.]githubusercontent[.]com/p00paboot/openapi-react-query-codegen/365d4eb738d3146583431948d3ba6e27a32556be/Raw GitHub URL for the malicious commit in the threat actor's fork
Detection / Hunteropenrouter
What Happened
A popular npm package used for generating React Query code from OpenAPI specifications was compromised when a hacker found a way to publish malicious versions that looked legitimate. The malicious software runs automatically when developers install the package, stealing passwords and access keys for services like GitHub, Amazon Web Services, and other cloud platforms. It then spreads itself by modifying other software packages and developer tools. Anyone who installed this package between August 28, 2026 and now should assume their computer and online accounts are compromised. They should disconnect the affected computer from the internet, change all their passwords and access keys, and reinstall the package using a known safe version.
Key Takeaways
- Ten malicious versions of @7nohe/openapi-react-query-codegen were published to npm with valid provenance attestations after a threat actor abused a comment-triggered GitHub Actions publishing workflow.
- The malicious packages execute a bundled, obfuscated JavaScript loader (3FWCvzduYZg.js) during installation via a malicious binding.gyp file or preinstall script, which decrypts and runs a second-stage payload.
- The second-stage payload targets cloud, package registry, GitHub Actions, and AI agent configuration credentials, and contains self-propagation functionality consistent with the Mini Shai-Hulud campaign.
- The attack abuses legitimate infrastructure like GitHub repositories for encrypted exfiltration and command retrieval, and Bun runtime downloads for secondary payload execution.
- The payload establishes persistence on macOS and Linux via LaunchAgents and systemd user services, and modifies developer tool configurations to ensure execution in future sessions.
Affected Systems
- npm/Node.js developer environments
- CI/CD runners using npm
- macOS systems
- Linux systems
- GitHub Actions runners
Vulnerabilities (CVEs)
None identified.
Attack Chain
- Initial Access: Malicious npm package @7nohe/openapi-react-query-codegen is installed via npm install, triggering the binding.gyp or preinstall script.
- Execution: The loader 3FWCvzduYZg.js is executed via node, which decrypts an embedded AES-128-GCM payload and writes it to a temporary file.
- Persistence: The payload establishes persistence via LaunchAgents on macOS, systemd user services on Linux, and modifications to developer tool configurations (e.g., settings.json, mcp.json).
- Credential Discovery: The payload scans the filesystem, process memory, environment variables, and cloud metadata services for credentials including GitHub, npm, PyPI, RubyGems, JFrog, AWS, Azure, and Google Cloud.
- Exfiltration: Collected credentials are encrypted using AES-256-GCM and RSA-OAEP, then exfiltrated to attacker-created public GitHub repositories.
- Lateral Movement: The payload propagates via SSH to reachable hosts, modifies GitHub Actions workflows to collect CI secrets, and poisons npm, RubyGems, JFrog, and PyPI packages with the malicious loader.
Detection Availability
- YARA Rules: No
- Sigma Rules: No
- Snort/Suricata Rules: No
- KQL Queries: No
- Splunk SPL Queries: No
- EQL Queries: No
- Other Detection Logic: No
No detection rules are provided in the article. The article provides IOCs and technical analysis that can be used to develop custom detections.
Detection Engineering Assessment
| Dimension | Rating | Rationale |
|---|---|---|
| EDR Visibility | Medium | EDR can observe process execution (node, python3, bun), file writes to persistence paths, and network connections. However, the use of legitimate binaries and GitHub infrastructure may blend with normal developer activity. |
| Network Visibility | Medium | Network monitoring can detect connections to cloud metadata services, GitHub API, and package registries. However, traffic to GitHub and npm registries is expected in developer environments, making it harder to distinguish malicious activity without behavioral context. |
| Detection Difficulty | Hard | The attack uses legitimate developer tools and infrastructure, making it difficult to distinguish from normal activity. The obfuscated payload and multiple execution paths add complexity. Detection requires correlating process behavior, file modifications, and network activity across multiple log sources. |
Required Log Sources
- Process execution logs (e.g., Sysmon Event ID 1, macOS process_monitoring)
- File creation and modification logs (e.g., Sysmon Event ID 11, 2)
- Network connection logs (e.g., Sysmon Event ID 3, DNS logs)
- npm install logs and package manager audit logs
- GitHub audit logs for repository creation, workflow changes, and artifact uploads
- Cloud provider metadata service access logs
Hunting Hypotheses
| Hypothesis | Telemetry | ATT&CK Stage | FP Risk |
|---|---|---|---|
| Hunt for processes executing node or python3 from temporary directories or unexpected paths, particularly following npm install or node-gyp build events. | Process execution logs, process ancestry, command line arguments | Execution | Medium - Developers may run scripts from temporary directories during testing or build processes. |
| Hunt for the creation of LaunchAgent plist files or systemd user service files with names not associated with standard software, particularly in user home directories. | File creation logs, file modification logs | Persistence | Low - User-level persistence mechanisms are less common and more suspicious, especially with random or unusual names. |
| Hunt for network connections to GitHub API endpoints (api.github.com) immediately followed by the creation of new public repositories or commits containing large base64-encoded blobs. | Network connection logs, GitHub audit logs, DNS logs | Exfiltration | Medium - Developers frequently interact with GitHub APIs, but automated repository creation with large encrypted blobs is unusual. |
| Hunt for modifications to developer tool configuration files (settings.json, mcp.json, .cursorrules) that add background commands or references to index.js files in .config directories. | File modification logs, file integrity monitoring | Persistence | Low - Modifications to developer tool configs that add hidden background tasks are highly suspicious and rarely legitimate. |
| Hunt for SSH connections originating from developer workstations or CI runners to multiple internal hosts with host-key checking disabled (StrictHostKeyChecking=no). | Network connection logs, SSH logs, process execution logs | Lateral Movement | Low - SSH with disabled host-key checking from developer machines is unusual and indicates potential lateral movement. |
Control Gaps
- Standard npm audit signatures will not flag these packages because they carry valid npm provenance attestations.
- Application allowlisting may not block the execution of node, python3, or bun as they are legitimate developer tools.
- Network security controls may not flag traffic to GitHub, npm, or cloud metadata services as these are common in developer environments.
- File integrity monitoring may not cover user-level persistence paths like ~/.config/systemd/user/ or ~/Library/LaunchAgents/.
Key Behavioral Indicators
- Process ancestry showing node or python3 spawned by npm install or node-gyp processes
- Creation of files named 3FWCvzduYZg.js, ai_init.js, or is_it_this_simple.js in temporary or package directories
- Modifications to binding.gyp files containing Unicode escape sequences or references to catch_warnings
- Creation of LaunchAgent or systemd service files with the name sysvinit-detect-fash
- Network connections to api.github.com/search/commits with the query parameter firedalazer
- Creation of public GitHub repositories with Touhou-themed names and the description 'Trinitite: Sponsored by Preview 2 Effects'
- GitHub Actions workflows named 'ClaudeCode Review' that serialize secrets into environment variables
- Commits with the message 'chore: update dependencies' that modify workflow files and add .github/_index.js
- Presence of the file /var/tmp/.shit on macOS or Linux systems
- SSH connections with StrictHostKeyChecking=no, BatchMode=yes, and PasswordAuthentication=no from developer workstations
False Positive Assessment
Medium
Recommendations
Immediate Mitigation
- Verify against your organization's incident response runbook and team escalation paths before acting. Immediately isolate any machine or CI runner that installed an affected version of @7nohe/openapi-react-query-codegen from the network.
- Identify and remove malicious persistence mechanisms (LaunchAgents, systemd services, developer tool config modifications) before revoking credentials, as the payload may trigger a destructive handler when its monitored GitHub token returns a 400-409 response.
- Revoke and rotate all credentials accessible from the affected environment, including npm tokens, GitHub tokens, cloud credentials, package registry credentials, and CI secrets.
- Pin @7nohe/openapi-react-query-codegen to a known-good version (0.5.3, 1.6.2, 2.2.0, or 3.0.2) and reinstall from a clean lockfile after clearing package-manager caches and removing existing node_modules.
- Review GitHub audit logs for unexpected repository creation, workflow file changes, deployment creation, commits named 'chore: update dependencies', and artifacts named 'reviewed'.
Infrastructure Hardening
- Evaluate whether your GitHub Actions workflows that publish packages use comment-triggered events (issue_comment) and gate only on comment text. If so, consider verifying the commenter's repository association (author_association) or moving publishing to a trigger that cannot be fired by an untrusted account.
- Consider implementing additional verification steps in CI/CD pipelines that check for unexpected file modifications or binding.gyp changes in JavaScript packages that do not have native implementations.
- Review and restrict the permissions granted to id-token: write in GitHub Actions workflows to only the minimum necessary jobs.
- Consider implementing network segmentation to restrict CI runners from accessing cloud metadata services unless explicitly required.
User Protection
- Consider deploying or enhancing file integrity monitoring on developer workstations to cover user-level persistence paths such as ~/Library/LaunchAgents/ and ~/.config/systemd/user/.
- Evaluate whether your EDR solution can detect and alert on process memory scanning behavior, particularly processes reading /proc/<pid>/maps and /proc/<pid>/mem on Linux systems.
- Consider implementing developer tool configuration policies that restrict or monitor modifications to settings.json, mcp.json, and similar files in developer tool directories.
Security Awareness
- Consider incorporating information about this supply chain attack into existing developer security awareness programs, emphasizing the risks of installing npm packages without version pinning and lockfile verification.
- Consider educating developers on the importance of reviewing GitHub Actions workflow configurations, particularly those involving package publishing and the use of issue_comment triggers.
- Consider reminding developers to report unexpected prompts to re-enter credentials or unusual behavior in their development environments, as these may indicate compromise.
MITRE ATT&CK Mapping
Initial Access
Execution
Persistence
Stealth
Credential Access
Command and Control
Exfiltration
Additional IOCs
- Urls:
hxxps://raw[.]githubusercontent[.]com/p00paboot/openapi-react-query-codegen/365d4eb738d3146583431948d3ba6e27a32556be/- Raw GitHub URL for the malicious commit in the threat actor's fork
- File Paths:
~/.local/bin/sysvinit-detect-fash.sh- Token monitor installer script path on Linux/macOS~/.config/sysvinit-detect-fash/fox- Token monitor configuration directory and file~/.config/sysvinit-detect-fash/fash-detected- Token monitor handler file containing executable shell code evaluated via eval~/Library/LaunchAgents/com.user.sysvinit-detect-fash.plist- macOS LaunchAgent persistence mechanism for the token monitor with RunAtLoad and KeepAlive set~/.config/systemd/user/sysvinit-detect-fash.service- Linux systemd user service persistence mechanism for the token monitor/var/tmp/.shit- File recording URL hashes of executed commands to prevent duplicate execution via the signed GitHub-commit command channel.config/index.js- Payload copy injected into developer tool configuration directories for persistence.github/_index.js- Payload injected into GitHub repositories via workflow poisoning to collect CI secretsai_setup.sh- Script copied to remote hosts via SSH for propagation
- Command Lines:
- Purpose: Trigger loader execution via node-gyp build process | Tools:
node,node-gyp,python| Stage: Initial Access |node 3FWCvzduYZg.js - Purpose: Preinstall script execution of loader | Tools:
node| Stage: Initial Access |"preinstall": "node 3FWCvzduYZg.js" - Purpose: Prerelease version preinstall fetching Bun installer and executing secondary script | Tools:
wget,bash,bun| Stage: Initial Access - Purpose: SSH propagation to remote hosts with host key checking disabled | Tools:
ssh,scp,bash| Stage: Lateral Movement - Purpose: GitHub token validation by checking HTTP status code | Tools:
curl| Stage: Credential Validation
- Purpose: Trigger loader execution via node-gyp build process | Tools:
- Other:
365d4eb738d3146583431948d3ba6e27a32556be- Malicious commit hash in the threat actor's fork used for stagingec7876d6c917dad516ba69bbfafc948b834bf0ab- Malicious commit hash for the second prerelease version pathfiredalazer- GitHub commit search query used as a rendezvous point for the signed command channeln1ggatr1n <base64-url>.<base64-signature>- Commit message format for the signed command channel carrying command location and signatureTrinitite: Sponsored by Preview 2 Effects- Description set on attacker-created public GitHub repositories used for exfiltrationchore: update dependencies- Commit message used by the GitHub Actions workflow poisoning module to hide malicious workflow modificationsClaudeCode Review- Name of the malicious GitHub Actions workflow that exfiltrates repository secrets via deployment events__DOGINSIDEPC- Environment variable used as a relaunch guard to detach the payload process from the parent build command