Injective SDK 1.20.21 on npm shipped a wallet stealer
Attacker pushed @injectivelabs/sdk-ts 1.20.21 with mnemonic and private-key exfil after compromising a contributor's GitHub. 310 installs before the pull.
The supply-chain incident of the day is small in downloads, big in
blast radius. On 2026-07-09
BleepingComputer reported
that an attacker pushed a malicious @injectivelabs/sdk-ts version
1.20.21 to npm after compromising the GitHub account of a legitimate
project contributor. The package’s normal job is generating and
importing Injective wallets. The tampered build stole the seeds and
keys as they went through it.
The legitimate maintainer caught the compromise within minutes, reverted the commits, and published a clean 1.20.23. But 310 installs of 1.20.21 had already gone out, and the package sits under an ecosystem that pulls ~50,000 weekly downloads across 87 direct dependents and roughly 112,000 cumulative dependent downloads. If any of those pinned to 1.20.21 or ran an unlocked install during the window, they got the malicious build.
What Socket, Ox Security, and StepSecurity found
According to the three research shops that analyzed the package, the malicious code activated on the SDK functions that generate or import a wallet — the ones you would call precisely when a mnemonic and private key are in memory. It captured the full seed phrase and private key, base64-encoded the payload, and shipped it out to an Injective Labs-adjacent infrastructure endpoint over HTTP.
The one operational detail worth flagging, per StepSecurity, is that the exfil was not immediate. The malware queued captured secrets for about two seconds before bundling them into HTTP request headers. That is a small delay chosen to smuggle the theft under normal-looking outbound traffic rather than trip a burst detector. Header-based exfil is not novel; the point is it looks like SDK telemetry to anyone not reading the payload.
Detection credit goes to Socket, Ox Security, and StepSecurity. The first suspicious commits landed on the compromised GitHub account on 2026-06-08. Everything after that — the npm publish, the detection, the revert, the 1.20.23 release — happened in a compressed window on 2026-07-09.
Here’s what to actually do
If your dependency tree has ever touched @injectivelabs/sdk-ts, do
these four things today, in this order.
- Grep every lockfile and manifest for 1.20.21.
package-lock.json,yarn.lock,pnpm-lock.yaml, and any container image you built in the window. If you find it, assume the environment that installed it ran the malicious code the moment any wallet-generation or wallet-import call went through the SDK. Pinning is not enough on its own — a lockfile that resolved to 1.20.21 during the window is a hit even if you later bumped it. - Move funds from any wallet whose seed or key was in memory during the window. Not “rotate later.” Move now, to a wallet generated on a machine that never installed 1.20.21. This is the same advice the researchers gave and it is not overreach — the exfil endpoint had the keys, in cleartext, base64-wrapped. Treat that as compromised.
- Rotate every other secret in the same environment. API keys, deploy tokens, cloud credentials, GitHub tokens that live in the same shell or CI runner. You do not know what else that process had access to, and rotation is cheap compared to the alternative.
- Force a resolve to 1.20.23 or later and pin it. Delete the
lockfile, reinstall from a clean cache (
npm cache clean --forcefirst), and commit the new lockfile. Confirm the resolved version in CI logs, not just locally.
Priority
Move the funds first. The malicious version was live long enough to land 310 installs; a small share of those are almost certainly production systems that generated or imported a wallet during the window, and every hour those seed phrases sit in an attacker-held inbox is an hour a drain script could run. Lockfile rotation and environment secret rotation are important, but a stolen mnemonic is the one that turns into a wire transfer.
The honest read on this one is the same as the Paysafe/Skrill/Neteller cluster Socket disclosed yesterday and the reason npm 12 flipped install scripts off by default: a compromised contributor account with publish rights is a full-tenant compromise of everything that pulls the package. The Injective case does not need install-time execution — the payload rides on functions you were going to call anyway. That is why the 310-install number is not the reassuring floor it looks like at first read; every one of those installs got the exact class of function they were reaching for the SDK to run.
Sources
- BleepingComputer — Injective SDK on npm infected with cryptocurrency wallet stealer (Bill Toulas, 2026-07-09)
- Socket — advisory on
@injectivelabs/sdk-ts1.20.21 (linked from the BleepingComputer report) - Ox Security — write-up on the compromise (linked from the BleepingComputer report)
- StepSecurity — analysis of the queued-header exfil (linked from the BleepingComputer report)
Found this useful? Share it.


