npm

The SubQuery npm Supply Chain Attack

Updated 23 Oct 2026 · Incident date 5 Oct 2026

Version 5.8.3 of @subql/common on npm carried a credential stealer. StepSecurity found that the hidden code starts when the package installs and again when a program imports it.

SubQuery uses this shared library in its blockchain data framework. On 10 October 2026, a project collaborator answered the report and said the team deleted the compromised token.

What happened

A new release added hidden code to the published package. StepSecurity downloaded the release, checked it and decoded the payload without running it.

Version 5.8.3 reached npm on 5 October 2026 at 11:56 UTC. The incident report says it came through the project's own npm trusted publisher. StepSecurity reports that commit 506863d6fb82 added a step to the publish job. That step downloads a replacement package from ci-artifacts.dev just before the publish, with no hash or signature check.

About 30 minutes earlier, a prerelease named 5.8.3-onf-rt1 reached npm under the tag redteam. Its description reads "RED TEAM VERIFICATION BUILD - harmless canary, ignore/unpublish." StepSecurity found that its code matches 5.8.2. StepSecurity says this prerelease does not establish that the later 5.8.3 release was authorized. The incident report asks the project to confirm whether the prerelease was an authorized test. The project's reply does not answer that question.

OpenSSF record MAL-2026-17571 lists 5.8.3 as malicious. It carries findings from Amazon Inspector and from GitHub malware advisory GHSA-9333-3c4x-x3h5. Amazon Inspector describes a new install hook and an encoded file. The file decodes hidden data and runs it as code. The source map leaves out the loader that the compiled JavaScript contains.

StepSecurity lists what the payload tries to collect. That includes package manager, SSH, cloud, Kubernetes, wallet and AI tool config files, plus the full process environment. It sends the data encrypted to ci-artifacts.dev. The same channel can take remote commands and open a shell. StepSecurity says it describes what the code attempts. It does not confirm any theft.

The incident report also describes a reverse shell and a spoofed GitHub branch and workflow. Project collaborator ianhe8x replied on 10 October that the team deleted the compromised token and started a review. The reply does not say how the attacker got access. On 23 October 2026, the issue is still open.

Affected versions

Only @subql/common 5.8.3 is malicious. Block it in package mirrors and build caches.

  • 5.8.2: the clean release before it, published 20 November 2025. It has no loader and no install hook.
  • 5.8.3-onf-rt1: a prerelease under the tag redteam. StepSecurity found that its code matches 5.8.2.
  • 5.8.3: the malicious release. Both install and import can start the payload.

Other SubQuery packages allow 5.8.3 through their version ranges, per StepSecurity. A project that never lists @subql/common can still get it through one of these:

  • @subql/cli@6.6.3 (range ~5.8.2)
  • @subql/node-core@19.3.1 (range ~5.8.2)
  • @subql/query@2.25.0 (range ~5.8.1)
  • @subql/node-ethereum@6.5.0 (range ^5.8.2)

StepSecurity reviewed 77 packages and found 19 with a possible path to 5.8.3.

On 23 October 2026, the npm registry no longer offers 5.8.3. Its latest tag points to 5.8.2. Its redteam tag still points to the prerelease. A clean dependency tree today does not show what an earlier build installed. Check old lockfiles, build logs and package caches too.

Indicators of compromise

StepSecurity, the incident report and Amazon Inspector list these indicators. They belong to the bad release and its payload.

  • Package version @subql/common@5.8.3
  • Release tarball SHA-256: 031267ee37c5a84c25cb0542cbfeb49f30d5604305b0bdccdeafbedcbbe6849b
  • Added file dist/project/readers/manifest-cache.js, SHA-256: f0c8b0cde86b98a2869a22fd43ffcf61f1dcca252729e2be291e590e3dc5f49a
  • Install hook node ./dist/project/readers/manifest-cache.js
  • Embedded array MANIFEST_CACHE_SEED in that file
  • Network destination ci-artifacts.dev/router
  • Lock file tmp.ts018051808.lock in the temp folder
  • Unexpected branch dependabot/github_actions/format/setup-formatter
  • Workflow .github/workflows/codeql_analysis.yml on that branch
  • Spoofed commit author github-advanced-security[bot]

A familiar workflow filename alone does not prove infection. Check the branch, where it came from and what the workflow does.

How to check

Check each project for the affected version. These commands list installed versions and read lockfiles. They do not load SubQuery code.

npm ls @subql/common --all
grep -n -A 8 -B 2 "@subql/common" package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null

Look for the added file and print its hash without running it. If the hash matches the one above, the machine has the bad release.

find node_modules -path "*/@subql/common/dist/project/readers/manifest-cache.js" -exec shasum -a 256 {} +

Run these checks in each deployed app, container image, CI workspace and developer machine. Search old build logs for 5.8.3. Search proxy and DNS logs for ci-artifacts.dev. Look in your repositories for the unexpected branch and workflow. Save evidence before you change an affected machine.

A copy in a cache shows that a build downloaded the release. It does not prove that the payload ran. Compare the cache date with install, build and process logs. Then list the affected machines, their service accounts and the repositories they can reach. Use that list to decide which credentials to rotate.

What to do now

  1. If 5.8.3 ran, isolate the machine or CI runner. Investigate it as compromised.
  2. From a clean machine, rotate every credential that the affected process can reach. Include npm, GitHub, SSH and cloud credentials.
  3. Check the repositories those credentials can reach for unexpected branches and workflows.
  4. Block version 5.8.3 and the domain ci-artifacts.dev. Remove copies of 5.8.3 from package mirrors and build caches.
  5. Pin @subql/common to 5.8.2 in your lockfile.
  6. Rebuild affected environments from trusted images. Removing the package does not cancel stolen credentials.

Turning off install scripts alone does not protect you. The release also starts its loader when a program imports it. Do not load a suspect copy to test it.

What Vigilance would show (rebuilt from public reports)

Vigilance compares the version you trust with the new one and names the file that gained a new power. The block below is rebuilt from the public reports in the words Vigilance prints. It is not a captured scan, because the malicious release is not redistributed.

vigi diff --old @subql/common-5.8.2 --new @subql/common-5.8.3
files scanned: 78

HEADS UP  1 file can now do things the old version could not. The rest changed and gained nothing.

CHANGED    dist/project/readers/manifest-cache.js
           It now reads saved passwords and access keys, runs other programs and runs a hidden, encoded command. It did not before.

Frequently asked questions

Is @subql/common safe to use?

Version 5.8.3 is malicious. Version 5.8.2 is the clean release before it, and npm now serves 5.8.2 as latest. Check old lockfiles and caches for 5.8.3.

Does --ignore-scripts protect against the @subql/common attack?

No. Version 5.8.3 also starts its payload when a program imports the package. StepSecurity says that turning off install scripts alone is not enough.

Was the SubQuery release a red team test?

No source confirms that. The redteam tag points to a separate prerelease whose code matches 5.8.2. StepSecurity says that prerelease does not establish that 5.8.3 was authorized. GitHub and OpenSSF list 5.8.3 as malware.

Sources

  1. stepsecurity.io/blog/subql-ecosystem-compromised
  2. osv.dev/vulnerability/MAL-2026-17571
  3. github.com/subquery/subql/issues/3047
  4. registry.npmjs.org/@subql/common

More supply chain attacks

All 122 attacks in the library · npm supply chain attacks · How to prevent supply chain attacks

Check the next update before you install it

Vigilance compares the version you trust with the new one. It names the one file that gained a power the old version did not have.

Start the free 14-day watchBrowse the attack library