# npm Supply Chain Attack: @injectivelabs/sdk-ts v1.20.21 and 17 Sibling Packages Infected with Cryptocurrency Wallet Stealer

> A compromised GitHub maintainer account (thomasRalee) was used to push malicious commits directly to master, publishing a backdoored v1.20.21 of @injectivelabs/sdk-ts and 17 dependent @injectivelabs scoped packages via an automated GitHub Actions trusted-publisher workflow. The payload exfiltrated BIP-39 mnemonic seed phrases and raw private keys, base64-encoded and smuggled inside an HTTP request header disguised as legitimate Injective gRPC-web telemetry, whenever SDK consumers generated or imported wallet keys.

- **Published:** 2026-07-09T00:00:00Z
- **Last reviewed:** 2026-07-09T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-1153
- **ID:** TL-2026-1153
- **Severity:** HIGH
- **Category:** SUPPLY_CHAIN
- **Status:** MITIGATED
- **Detections:** 9 · **IOCs:** 20 (full data via the Threadlinqs MCP server — Purple tier)

## Description

On 2026-07-08 an attacker with write access to the GitHub account `thomasRalee` — a trusted, existing maintainer of the InjectiveLabs/injective-ts monorepo with direct push permissions to master — committed a new file, `src/utils/key-derivation-telemetry.ts`, and wired its `trackKeyDerivation()` function into the static `PrivateKey.fromMnemonic()` and `PrivateKey.fromHex()` methods inside `PrivateKey.ts`. Both malicious commits landed directly on master with no associated pull request, indicating either a bypassed branch-protection rule or full write access consistent with account takeover rather than a stolen npm publish token, dependency confusion, or typosquatting.

The payload intercepted the full BIP-39 mnemonic phrase or raw hex private key the instant a consumer application called wallet-generation or wallet-import functions — before legitimate key-derivation logic executed. Captured secrets were formatted as `{method}:{value}:{timestamp}` (e.g. `fm:wallet phrase:1783975179000`), base64-encoded via `Buffer.from(s,'utf-8').toString('base64')` in Node or `btoa(s)` in browser contexts, and queued in a 2-second `setTimeout` window so multiple captured keys/mnemonics from a single session could be pipe-delimited (`|`) and batched into one exfiltration request rather than firing per-capture (evading simple rate-based detections).

The exfiltration endpoint was `https://testnet.archival.chain.grpc-web.injective.network/`, a domain that mimics legitimate Injective Labs public infrastructure naming conventions so closely that it blends into normal SDK network traffic. The hostname itself was not hardcoded as a plain string but obfuscated as a JavaScript numeric character-code array and reconstructed at runtime via `String.fromCharCode()`, defeating simple static grep-for-domain scans. The exfiltration HTTP POST carried `Content-Type: application/grpc-web+proto` to visually mimic legitimate Injective gRPC-web calls, an empty request body, and the base64-encoded stolen secret placed entirely inside the `X-Request-Id` header — a location unlikely to be inspected or logged by standard web/network security tooling that focuses on request bodies.

A GitHub Actions trusted-publishing (OIDC) workflow auto-published the compromised code to npm as soon as a version-bump commit landed, meaning the attacker did not need a separate stolen npm token — control of the GitHub account alone was sufficient to reach the npm registry for all 18 packages within minutes. The malicious v1.20.21 release went live across the entire @injectivelabs 1.20.21 release train (sdk-ts plus 17 packages pinning that exact sdk-ts version) and remained live for approximately 49-50 minutes before the same account (thomasRalee) authored a revert commit and the maintainers republished a clean v1.20.23. During the exposure window the malicious tarball was downloaded 310 times; the SDK carries roughly 50,000 weekly downloads overall and has 87 direct dependents with a cumulative ~112,000 downloads, making the blast radius of any developer or CI pipeline that happened to `npm install` during that ~50-minute window nontrivial. Application security vendors Socket, Ox Security, and StepSecurity independently detected and disclosed the compromise. As of disclosure the deprecated v1.20.21 npm release (and its corresponding GitHub release artifacts) remained retrievable rather than fully removed, meaning cached copies, private registry mirrors, or lockfiles pinned to the exact version and integrity hash could still deliver the malicious code after the public window closed.

No CVE has been assigned. No public threat-actor attribution has been disclosed; the account-takeover vector (credential theft, session/token hijack, or social engineering of the maintainer) has not been confirmed by any source at time of writing.

## MITRE ATT&CK

- T1586 Compromise Accounts
- T1583.006 Web Services
- T1587.001 Malware
- T1195.002 Compromise Software Supply Chain
- T1195.002 Compromise Software Supply Chain
- T1199 Trusted Relationship
- T1078 Valid Accounts
- T1204 User Execution
- T1204.003 Malicious Image
- T1554 Compromise Host Software Binary
- T1027 Obfuscated Files or Information
- T1027.010 Command Obfuscation
- T1036.005 Match Legitimate Resource Name or Location
- T1140 Deobfuscate/Decode Files or Information
- T1070.004 File Deletion
- T1555.003 Credentials from Web Browsers
- T1528 Steal Application Access Token
- T1552.004 Private Keys
- T1005 Data from Local System
- T1119 Automated Collection
- T1074.001 Local Data Staging
- T1071.001 Web Protocols
- T1132.001 Standard Encoding
- T1071 Application Layer Protocol
- T1041 Exfiltration Over C2 Channel
- T1567 Exfiltration Over Web Service
- T1029 Scheduled Transfer
- T1657 Financial Theft

## Sources

- [Injective SDK on npm infected with cryptocurrency wallet stealer](https://www.bleepingcomputer.com/news/security/injective-sdk-on-npm-infected-with-cryptocurrency-wallet-stealer/)
- [Injective npm Supply Chain Attack: 18 Packages Backdoored to Steal Crypto Wallet Keys](https://www.stepsecurity.io/blog/injective-npm-supply-chain-attack-18-packages-backdoored-to-steal-crypto-wallet-keys)
- [@injectivelabs/sdk-ts - npm package page](https://www.npmjs.com/package/@injectivelabs/sdk-ts)
- [@injectivelabs/wallet-ts npm Package Security Analysis - Socket](https://socket.dev/npm/package/@injectivelabs/wallet-ts)
- [InjectiveLabs/injective-ts GitHub repository](https://github.com/InjectiveLabs/injective-ts)
- [InjectiveLabs/injective-chain-releases GitHub repository](https://github.com/InjectiveLabs/injective-chain-releases)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-1153
