A brief window of stolen access was all it took to turn a trusted open-source package into a malware delivery vehicle. Researchers at CloudSEK have detailed a supply-chain attack, dubbed GHAPPIER, in which an attacker took over a maintainer account for just 105 minutes and used that time to insert a hidden, multi-stage loader into a widely used npm package, then rewrote the project’s release automation so the poisoned version would publish itself without further human involvement.
A narrow window, a wide blast radius
On September 9, 2026, the attacker gained control of the maintainer account behind @dforge-core/dforge-mcp. In the 105 minutes they held access, they buried a remote loader deep inside the codebase, hidden near line 3,320 of a 99 KB file where it would be easy to overlook during casual review. They then modified three lines to trigger the project’s release workflow directly from the main branch and altered the publishing pipeline to allow it to run unattended.
CloudSEK’s investigation found that the attack ultimately touched 22 accounts, 65 GitHub repositories, and 73 files, a reminder that compromising a single, well-connected maintainer account can cascade far beyond the original target.
Abusing trust in the publishing pipeline itself
What makes GHAPPIER notable isn’t just what was hidden in the code, but how convincingly legitimate the malicious release looked. The attacker’s changes rode through GitHub Actions and OpenID Connect trusted publishing, the same mechanisms legitimate maintainers use to automate releases. As a result, the poisoned package carried valid npm provenance, and its build attestation in Sigstore, a system designed to verify software authenticity, faithfully recorded the attacker’s own commit as if it were routine.
The malicious release, version 0.2.21, remained the package’s latest published version for 35 minutes and 38 seconds before being pulled and replaced with a clean 0.2.22. That’s a narrow exposure window, but not necessarily a safe one; anyone who installed or ran the package during that span may have executed the hidden loader.
What the payload actually did
CloudSEK’s analysis describes a four-stage payload chain launched from the single hidden line of code. Rather than reaching out to a conventional command-and-control domain, the malware pulled its instructions from a transaction recorded on the Ethereum blockchain, an increasingly common evasion technique since blockchain-based infrastructure is far harder for defenders to take down than a domain or IP address. The final stage of the chain deleted itself after execution, an anti-forensics step intended to reduce the odds that a later disk search would turn up evidence of the implant.
Despite the package being pulled quickly, CloudSEK found that all stages of the attack infrastructure still responded when tested five days after the malicious version was withdrawn, underscoring a critical point: removing a poisoned package from a registry stops new downloads, but it does nothing to disable the attacker’s backend or warn anyone who already installed it.
How the account was likely compromised
The exact initial access method hasn’t been confirmed, but researchers point to a plausible link with the PolinRider malware campaign, which is known to harvest cached Git credentials from infected developer machines. That would let an attacker push code and trigger releases under a legitimate maintainer’s identity without ever needing their password. CloudSEK also identified a second, related payload in another victim repository tied to the same PolinRider family, suggesting this wasn’t an isolated incident but part of a broader pattern of credential theft feeding into supply-chain compromises.
The underlying architectural problem
CloudSEK frames the incident as evidence of a structural weakness in how open-source publishing trust is built: write access to a repository effectively became publishing access to its releases, collapsing two permissions that arguably should be kept separate. As the researchers put it, trusted publishing, source control access, and developer devices all end up belonging to the same security boundary, meaning a compromise of any one of them can compromise all three.
Organizations that use @dforge-core/dforge-mcp should pin to version 0.2.22 or later, verify that the malicious 0.2.21 release was never installed or executed in their environment, and rotate any credentials that may have touched affected systems. More broadly, maintainers and organizations relying on automated release pipelines should audit who can trigger a release, restrict main-branch write access, and treat developer endpoint security as inseparable from software supply-chain security.
Leave a Reply
You must be logged in to post a comment.