Red Hat npm backdoor shows the registry trust gap

ReversingLabs found 31 Red Hat-scoped npm packages backdoored in a 72-second burst. The key issue is package registry access, not just source code trust.

2026-06-01 GIGATAP Team #security
#software supply chain#npm#open source security

Source: ReversingLabs Blog — https://www.reversinglabs.com/blog/31-red-hat-cloud-service-npm-packages-backdoored-in-72-seconds

ReversingLabs says 31 npm packages under Red Hat’s Hybrid Cloud Console JavaScript ecosystem were backdoored in a 72-second publishing burst on June 1, 2026. The operational signal is sharper than the package count: the affected packages came from two different GitHub repositories, but the malicious releases landed under the same npm scope. RL’s read is that this points to npm scope credential compromise, not a normal source repository compromise.

That distinction matters for software supply chain response. If the attacker can publish to the package registry directly, a clean GitHub repository does not prove the package version installed by users was clean.

What changed#

According to ReversingLabs, the attacker published malicious versions of 31 packages between 10:54:09 and 10:55:21 UTC. The packages collectively account for about 9.8 million total downloads and cover UI components, API clients, build tooling, configuration utilities, and MCP servers in Red Hat’s Hybrid Cloud Console JavaScript ecosystem.

RL lists affected packages including @redhat-cloud-services/chrome, @redhat-cloud-services/frontend-components, @redhat-cloud-services/insights-client, @redhat-cloud-services/rbac-client, @redhat-cloud-services/vulnerabilities-client, @redhat-cloud-services/compliance-client, and others under the same npm scope.

The timing is the first useful clue. Thirty-one publishes in 72 seconds is not an operator manually editing and shipping one package at a time. RL describes it as automated scripted publishing: the poisoned archives were likely prepared in advance, then pushed in one batch.

The second clue is the modification pattern. ReversingLabs says each affected package changed in the same narrow way compared with its prior clean version:

  • a preinstall script was added to package.json, pointing execution to index.js
  • the package’s normal index.js was replaced with a malicious obfuscated payload
  • no other files were changed

That is a small diff with a large blast radius. preinstall runs during installation, before the consuming project ever imports the package. In practice, that makes the install step itself the execution point.

Why the software supply chain risk changes#

This is not just another “malicious package uploaded to npm” story. The more important issue is trust boundary confusion.

Developers often treat the source repository as the canonical object. That is useful, but incomplete. The install path usually trusts the package registry artifact. If registry publishing credentials are compromised, the attacker may not need to alter GitHub source code, pull requests, issue history, or CI logs. They can ship a version that looks legitimate by namespace and package name, while differing from the source tree users think they are consuming.

ReversingLabs notes that the affected packages span two GitHub repositories: RedHatInsights/frontend-components and RedHatInsights/javascript-clients. That cross-repository spread is why RL argues the compromise was at the npm scope credential level. If that assessment is correct, incident response has to focus on maintainer access, tokens, publishing workflow, and registry-side controls — not only repository cleanup.

The malicious code design also shows planning. RL describes a multi-layer obfuscation chain: a ROT-N Caesar-style layer, AES-128-GCM decryption, and an obfuscator.io payload. The outer wrapper reconstructs a large encoded string and applies a rotation. The decoded layer then decrypts two blobs using Node.js crypto. One blob downloads the Bun runtime from the official GitHub release location into a temporary directory; the second is the main payload, written to a temp file and executed with Bun.

That Bun detail should not be overread as a problem with Bun itself. Based on RL’s description, the runtime download appears to be a staging choice by the attacker: use a legitimate binary from a legitimate source, then execute the payload through it. The security issue is the malicious package install path and the compromised publishing trust, not the existence of Bun.

What to check before acting#

The first check is simple: determine whether any build, developer machine, CI runner, container image, or lockfile consumed the malicious package versions named by ReversingLabs. Do not stop at direct dependencies. These packages include shared clients and frontend components, so transitive exposure is plausible depending on the consuming project.

Practical checks:

  • review package-lock.json, yarn.lock, pnpm-lock.yaml, and build logs for the affected @redhat-cloud-services/* packages
  • compare installed versions and install timestamps against the June 1 publishing window cited by RL
  • inspect CI logs for preinstall execution from these packages
  • check whether any install occurred on machines or runners with access to npm tokens, cloud credentials, SSH keys, GitHub tokens, or internal package registry credentials
  • rotate credentials exposed to affected install environments if compromise cannot be ruled out
  • rebuild artifacts from known-clean dependency versions rather than trusting existing build output

The highest-risk hosts are not always production servers. In supply chain incidents, build systems and developer workstations often hold better secrets than runtime containers. A malicious preinstall does not need the application to start. It only needs someone to install dependencies in a useful environment.

For teams already working on dependency integrity, this is a case for making package provenance operational rather than decorative. Trusted publishing, short-lived tokens, registry-side two-factor enforcement, artifact verification, and lockfile review are not abstract best practices here. They are controls aimed at the exact seam RL describes: who can publish, what was published, and whether the artifact matches the expected source.

Related reading: OpenSSF’s April signal: make security artifacts operational and 100% package test coverage is the point, not the slogan.

What not to overclaim#

The source material supports a strong claim about malicious npm package versions and a likely scope-level publishing compromise. It does not, from the provided details, prove which specific credentials were stolen, how the attacker obtained them, whether every downloader was compromised, or what data the final payload successfully collected.

That uncertainty is important. A package with millions of total downloads does not mean millions of compromised systems. Total download counts include historical usage, automated mirrors, cache behavior, CI churn, and repeated installs. The real exposure depends on who installed the malicious versions during the affected window and what secrets were available in those environments.

It is also worth separating source integrity from package integrity. A repository can remain clean while registry artifacts are poisoned. That is exactly why open source security checks need to cover the full release path: maintainer access, package registry permissions, CI publishing rules, install scripts, artifact diffs, and post-install behavior.

The useful takeaway is narrow and serious. Treat package publishing access as production access. A registry token with scope-level rights can turn trusted names into execution channels faster than most teams can notice manually. In this case, RL says it took 72 seconds.