Mini Shai-Hulud Supply-Chain Attack Compromises 10 npm Package Versions

Summary
Ten malicious versions of @7nohe/openapi-react-query-codegen were published through an abused GitHub Actions workflow. The package’s install-time payload steals credentials and can propagate through developer and CI environments.
Key points
- Ten versions published on August 28, 2026, remain installable; the latest tag points to compromised version 3.0.4. Last known-good releases are 0.5.3, 1.6.2, 2.2.0, and 3.0.2.
- An issue-comment workflow allowed untrusted users to publish code from a pull-request fork by commenting “npm publish”; the job used GitHub Actions trusted publishing.
- The malicious package executes an obfuscated payload during installation, using a binding.gyp build trigger and, in some versions, a preinstall script.
- The payload searches files, process memory, cloud metadata, and CI variables for credentials, then can exfiltrate data and abuse package-registry and GitHub permissions.
- Additional capabilities include CI workflow tampering, developer-tool persistence, SSH propagation, and monitoring for GitHub tokens.
- Valid npm provenance attestations did not ensure the published tarballs contained trusted code; npm audit signatures may not flag these versions.
- Socket advises isolating affected systems, addressing persistence, rotating exposed credentials, checking for affected versions, and pinning to a known-good release.
Article Details
- Attack Vectors
- An untrusted GitHub account could comment `npm publish` on a pull request to trigger a publishing workflow that checked out the fork's code without checking the commenter's repository association.
- The workflow published attacker-modified versions of @7nohe/openapi-react-query-codegen through GitHub Actions trusted publishing, giving all ten malicious releases valid npm provenance attestations.
- Installation of the affected releases executed an obfuscated JavaScript loader through binding.gyp; later releases also used a preinstall script. The two malicious prereleases used separate preinstall paths.
- The decrypted payload contains credential discovery and validation, encrypted exfiltration to attacker-created public GitHub repositories, package poisoning, GitHub Actions workflow modification, developer-tool configuration persistence, and SSH propagation. The reported analysis was based on static inspection; the payload was not executed by the researchers.
- Defensive Notes
- Isolate systems and CI runners that installed an affected version. Prefer rebuilding from a known-clean image and check for persistence before rotating exposed credentials.
- Contain the host and disable the reported GitHub-token monitor before revoking or testing its token: an HTTP 400–409 response can cause the monitor to evaluate its stored handler.
- Pin @7nohe/openapi-react-query-codegen to a last 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 existing node_modules.
- Check lockfiles and SBOMs for all ten affected versions, including transitive installations. Do not rely on npm audit signatures or valid provenance attestations to identify these releases.
- Review GitHub audit logs, package-registry publishing activity, the reported persistence paths, developer-tool configurations, and SSH logs for follow-on activity.
- Maintainers should verify commenter repository association before allowing an issue_comment-triggered publishing job with id-token: write, or use a trigger that an untrusted account cannot invoke.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| SHA256 | 59370c67b54a0ccaedd265e2356f04540b2fba1e1845300ef6de4d5437d99380 | Hash listed for the malicious 3FWCvzduYZg.js loader. |
| SHA256 | b49afb7dba04cd99b357ce7c652c823a3707f28e130bd5c6645851a7adc030d6 | Hash listed for the malicious 3FWCvzduYZg.js loader. |
| SHA256 | d3246926b20a8d021ed7de0ac8e9eee1dda986088f84ba18f31cb2042a121f5d | Hash listed for the malicious binding.gyp build trigger. |
MITRE ATT&CK
T1021.004 · SSHThe recovered propagator uses SSH and scp to copy scripts to reachable hosts and run the implant remotely.T1027 · Obfuscated Files or InformationThe installation loader uses single-byte XOR obfuscation, while the binding.gyp command is concealed with Unicode escapes.T1059.006 · PythonThe binding.gyp condition uses a Python expression to invoke os.system, and the recovered payload uses Python modules for memory reading and command execution.T1059.007 · JavaScriptInstallation runs the malicious JavaScript loader with node; the loader decrypts and executes a second-stage payload.T1102.001 · Dead Drop ResolverThe recovered harvester searches GitHub commits for signed messages containing a URL from which it downloads and executes a Python command.T1195.001 · Compromise Software Dependencies and Development ToolsThe actor published malicious versions of @7nohe/openapi-react-query-codegen and the recovered payload contains functionality to poison other writable packages.T1528 · Steal Application Access TokenThe payload seeks GitHub, npm, and other application tokens in files, process memory, and environment variables, then validates them for reuse.T1543.001 · Launch AgentOn macOS, the token-monitor installer creates and bootstraps a persistent LaunchAgent with RunAtLoad and KeepAlive.T1543.002 · Systemd ServiceOn Linux, the token-monitor installer creates and enables a persistent user systemd service.T1552.001 · Credentials In FilesThe payload recursively scans files, including dotfiles, for tokens and other secrets.T1552.005 · Cloud Instance Metadata APICloud-provider modules query instance metadata endpoints to obtain credentials.T1567.001 · Exfiltration to Code RepositoryA recovered module creates public GitHub repositories and commits encrypted collections of stolen findings to them.
Vendors
GitHubTen malicious versions were published with valid npm provenance after a threat actor abused a comment-triggered GitHub Actions publishing workflow, with the latest release still compromised at the time of writing.JFrogvalidation and use of GitHub, npm, PyPI, RubyGems, and JFrog credentials;npmTen malicious versions were published with valid npm provenance after a threat actor abused a comment-triggered GitHub Actions publishing workflow, with the latest release still compromised at the time of writing.PyPIvalidation and use of GitHub, npm, PyPI, RubyGems, and JFrog credentials;RubyGemsvalidation and use of GitHub, npm, PyPI, RubyGems, and JFrog credentials;
Products
@7nohe/openapi-react-query-codegenTeam is investigating an ongoing Mini Shai-Hulud compromise, affecting the npm package @7nohe/openapi-react-query-codegen. On August 28, 2026, ten malicious versions were published in two waves roughly twentyBun0.0.0-365d4eb738d3146583431948d3ba6e27a32556be uses a preinstall script that fetches and runs the Bun installer, then executes is_it_this_simple.js with WORKFLOW_ID=release.yml,GitHub ActionsTen malicious versions were published with valid npm provenance after a threat actor abused a comment-triggered GitHub Actions publishing workflow, with the latest release still compromised at the time of writing.node-gypPython expression to reach os.system and run node 3FWCvzduYZg.js. Because binding.gyp is processed by node-gyp during installation, this fires on npm install in developer environments and CI runners.