HighSupply chainMonitoring

GHAPPIER loader reached npm through trusted publishing, riding a maintainer account into @dforge-core/dforge-mcp 0.2.21

A loader shipped in @dforge-core/dforge-mcp 0.2.21 with valid npm provenance via GitHub Actions trusted publishing, in 65+ repos. Pin 0.2.22, rotate tokens.

Published
Updated
Fixed in
No security release. The maintainer reverted the loader and published a clean 0.2.22; 0.2.21 remains the indicator to search for
Exploitation
Yes. The malicious @dforge-core/dforge-mcp 0.2.21 was published to npm, and CloudSEK found every stage of the chain still responding five days after it was withdrawn

What happened

CloudSEK named the operation GHAPPIER and reported it on 20 September 2026. The same loader appears across at least 65 public repositories, in 73 infected files, tied to 22 accounts (CloudSEK; Infosecurity Magazine).

  • 9 September 2026: an intruder used the maintainer account of @dforge-core/dforge-mcp for 105 minutes. In that window they added a remote code loader, changed three lines so any push to main started the release workflow, and 14 minutes later rewrote that workflow so it could publish unattended (CloudSEK).
  • Release 0.2.20 failed and broke installation of the package. Release 0.2.21 carried the loader and was the latest version on the registry for 35 minutes and 38 seconds before the maintainer reverted and published a clean 0.2.22 (Infosecurity Magazine).
  • CloudSEK could not establish how the attacker already had push access to main. It suspects a developer machine infected by a malicious extension or package, and considers cached-git-credential harvesting the most plausible route (CloudSEK; Infosecurity Magazine).
  • As of the report, no advisory had appeared in OSV, the GitHub advisory database, or from the maintainer, so users of 0.2.21 had no official notice. Five days after withdrawal, every stage of the chain still responded when tested (CloudSEK).

How trusted publishing was abused

  • The malicious release was built by GitHub Actions through OIDC trusted publishing and carried valid npm provenance. Its Sigstore attestation names the attacker’s own commit, and the release passed npm audit signatures (Infosecurity Magazine).
  • No npm credential was needed. Because the registry trusts the repository’s CI identity, push access to the repository amounted to publish access (Infosecurity Magazine).
  • Nothing was forged. As CloudSEK puts it, provenance attests “where an artefact was built, not whether its source was honest” (CloudSEK).

What the loader does

All details from CloudSEK and Infosecurity Magazine.

  1. The payload is a single line at position 3320 of a 99 KB file. It opens a four-stage chain ending in a general-purpose remote shell.
  2. The final implant deletes itself from disk as it runs, so a file search will not find it. Defenders should look for the artefacts the chain leaves behind.
  3. It fires when the MCP server is launched, not on npm install. Systems that installed 0.2.21 without launching it did not run the loader.

A second payload family found in another victim’s repository matched PolinRider, a campaign OpenSourceMalware has tracked across thousands of repositories since March 2026. That sample has no hardcoded C2: it reads its configuration from the 20-byte recipient address of an empty Ethereum transaction costing about twenty cents, leaving no domain or host to take down. Other researchers attribute PolinRider to North Korea; CloudSEK cites this rather than asserting it, and its one independent check did not confirm it (CloudSEK).

Affected packages / accounts

  • Named package: @dforge-core/dforge-mcp, version 0.2.21 only. The maintainer account was compromised; the clean release is 0.2.22 (CloudSEK).
  • Wider spread: the same loader is present across at least 65 public repositories, 73 infected files, and 22 accounts. CloudSEK does not name the other repositories or accounts on the page (CloudSEK; Infosecurity Magazine).
  • CloudSEK found no exploitation of GitHub, npm, or any package, and no evidence of a successful compromise of any organization. It describes the exposed population as small (Infosecurity Magazine).

What to do

  1. Pin @dforge-core/dforge-mcp at 0.2.22. Treat any lockfile that still pins 0.2.21 as an indicator of compromise (CloudSEK).
  2. Rotate secrets reachable by any process that launched an affected MCP server, since the loader runs on launch and ends in a remote shell (Infosecurity Magazine).
  3. Sweep for the chain’s artefacts, not the implant, because the final stage deletes itself from disk (CloudSEK).
  4. Alert on changes to a release workflow’s trigger block. Here the trigger change came 14 minutes before the workflow could publish unattended (CloudSEK).
  5. Do not rely on provenance alone. A valid Sigstore attestation and passing npm audit signatures here recorded an honest build of dishonest source (Infosecurity Magazine).

Why this matters

Trusted publishing was meant to remove long-lived npm tokens from the supply chain. GHAPPIER shows the trade-off: once the registry trusts a repository’s CI identity, whoever can push to main can publish, and the resulting package carries genuine provenance. The attestation is true and the artefact is still malware.

Sources