Skip to content

Back to the catalog

Injective npm Supply Chain Attack: 18 Packages Backdoored to Steal Crypto Wallet Keys
stepsecurity.iowriteup

Injective npm Supply Chain Attack: 18 Packages Backdoored to Steal Crypto Wallet Keys

On July 8, 2026, a compromised maintainer account pushed malicious commits directly to the master branch of the InjectiveLabs/injective-ts monorepo, triggering the repo's own OIDC-based GitHub Actions publish pipeline to release backdoored version 1.20.21 of @injectivelabs/sdk-ts and 17 dependent packages. The payload, disguised as 'key derivation telemetry,' hooked PrivateKey.fromMnemonic() and PrivateKey.fromHex() to capture BIP-39 seed phrases and raw private keys, batched and base64-encoded them, and exfiltrated them via the X-Request-Id header of HTTPS requests to a typosquat-style domain (testnet.archival.chain.grpc-web.injective.network) mimicking legitimate Injective gRPC-Web traffic. The destination hostname was obfuscated as a JavaScript char-code array to evade plaintext string scans, and the packages were reverted to clean 1.20.23 roughly 49 minutes after the malicious release.

TL;DR A compromised maintainer pushed a backdoor straight to master, causing the trusted CI/OIDC pipeline to auto-publish 18 malicious @injectivelabs npm packages that stole crypto wallet seed phrases/private keys via header-based exfiltration to a lookalike domain.
Document

What it is

A software supply-chain backdoor in @injectivelabs/sdk-ts, Injective Labs' official TypeScript SDK for building against the Injective blockchain (wallets, DEX frontends, trading bots, indexers). On July 8, 2026, malicious version 1.20.21 was published across 18 @injectivelabs npm packages and republished clean at 1.20.23 about 49 minutes later. The payload stole BIP-39 seed phrases and hex private keys.

How it works

Three commits went straight to master of InjectiveLabs/injective-ts under the identity of established maintainer thomasRalee (thomas.leera@gmail.com) — no PR, all labeled "chore: add key derivation telemetry." The version-bump commit 5486f13e799d9c90095c5f581a04ad867d768f66 triggered the repo's own GitHub Actions trusted-publisher (OIDC) pipeline (.github/workflows/publish.yaml, run 28975012939). No npm token was stolen; only GitHub write access was needed, meaning direct-push rights or bypassed branch protection — consistent with a compromised legitimate account.

The 79-line key-derivation-telemetry.ts added a trackKeyDerivation() call inside both PrivateKey.fromMnemonic() and PrivateKey.fromHex() — the canonical entry points every wallet-holding app calls with its most sensitive secret. The exfil host is stored as a char-code array reassembled at runtime to testnet.archival.chain.grpc-web.injective.network, crafted to mimic real Injective gRPC-Web infrastructure and to defeat a naive grep -rn "https://" scan.

Preconditions / Affected

  • Installed any of the 18 @injectivelabs packages at exactly 1.20.21 during the ~49-minute window, or picked up a cached copy since.
  • The 17 non-sdk-ts packages contain no payload themselves but pin @injectivelabs/sdk-ts@1.20.21 exactly, so installing any of them pulls the backdoored SDK transitively.
  • Only matters if the app constructs or loads a key via fromMnemonic() / fromHex() while the bad version was present.

What to do

  • Ensure no lockfile or cache resolves @injectivelabs/sdk-ts (or its 17 siblings) to 1.20.21; move to 1.20.23 or later.
  • Grep source and cache for the reassembled domain and its char-code form, not just literal https://:
testnet.archival.chain.grpc-web.injective.network
  • Treat as compromised any wallet secret that passed through fromMnemonic() / fromHex() during the window — the page says to consider those seed phrases and private keys exposed and (by implication) rotate/migrate funds.

Caveats

  • The page states the 17 sibling packages were confirmed clean of the payload itself; their risk is purely transitive via the exact-version pin.
  • Text is truncated ("only 4…") — the full exfiltration mechanics (transport, encoding of the stolen key, C2 request shape) are not shown here, so verify against the source page before building detections on payload format.

Organisations named here

  • Injective
  • testnet.archival.chain.grpc-web.injective.network

Technologies named here

  • @injectivelabs/sdk-ts
  • GitHub Actions
  • 17 @injectivelabs scoped packages depending on sdk-ts
  • npm
  • TypeScript
  • Node.js
  • OIDC

Techniques named here

  • Compromised maintainer account / direct push to master
  • Malicious package update disguised as benign feature
  • Runtime code-path injection
  • String/domain obfuscation via character-code array
  • Exfiltration disguised as legitimate protocol traffic
  • Batching and encoding of exfiltrated data
  • Silent failure handling to avoid detection

Threat actors named here

  • thomasRalee