PatchDay Alert
Analysis · 7 min read · 1,442 words By Colten Anderson · Commentary

Three CVEs keep getting called the Nx attack, and only one of them is this one

An 18-minute window on the VS Code marketplace ended with 3,800 of GitHub's own repositories copied. The interesting part isn't the speed. It's the delivery channel nobody was watching.

Three CVEs keep getting called the Nx attack, and only one of them is this one

Read the headlines from the last few weeks and you’d conclude that “the Nx attack” is a single event: someone poisoned the Nx ecosystem, AI tools helped the malware hunt for secrets, and GitHub lost thousands of internal repositories. That story is wrong in a specific and useful way. There is no Nx attack. There are three of them, they happened across ten months, and they get conflated constantly because Nx sits at the center of all three.

The one that copied approximately 3,800 of GitHub’s internal source-code repositories is CVE-2026-48027, a trojanized release of Nx Console, the Nx editor extension for VS Code. It was live on the Visual Studio Marketplace for about 18 minutes on May 18, 2026. If you ran Nx Console v18.95.0 in that window, the action you own is short and unpleasant, and it’s at the bottom of this post. But the reason this one is worth your attention as the person setting patch priority isn’t the speed of the breach. It’s where the attack came from, and the fact that almost nobody is watching that door.

Untangling the three

Start by separating the events, because the IOCs and the lessons do not transfer between them.

CVE-2025-10894, “s1ngularity” (August 2025). This is the npm one, and the origin of the AI-assisted-malware story. Attackers used a pull_request_target GitHub Actions injection against the nrwl/nx repo to steal Nx’s npm publish token, then pushed eight malicious nx versions to npm. The payload fired via npm postinstall, and the part that made headlines was that it invoked locally installed AI CLIs (Claude Code, Gemini, Amazon Q) with their guardrail-skipping flags to help find secret files. Its second wave made 6,700-plus private repositories public across roughly 2,180 GitHub accounts.

CVE-2026-45321, the TanStack compromise (May 11, 2026). Attackers poisoned 40-plus @tanstack/* npm packages. A legitimate Nx contributor’s machine pulled one (@tanstack/zod-adapter) during an install, and its prepare script stole that developer’s GitHub CLI OAuth token. Reporting puts this at CVSS 9.6, not yet NVD-confirmed. This is the upstream hop, and it matters only because of what the stolen token unlocked next.

CVE-2026-48027, Nx Console (May 18, 2026). This is the post. Using the GitHub token stolen in the TanStack chain, the attacker published a malicious Nx Console editor extension, not an npm package, to the VS Marketplace and Open VSX. Reporting cites CVSS 9.3, also not yet NVD-confirmed; the vendor GHSA advisory and the CISA KEV listing are the authoritative records.

The honest framing: August 2025 was the dress rehearsal, and May 2026 was the escalation. Same ecosystem, harder-to-spot delivery channel. If you pin the “s1ngularity” name or the s1ngularity-repository-* exfil indicators to CVE-2026-48027, you’ll hunt for the wrong artifacts.

The pattern: a marketplace is a software supply chain too

Here is the structural observation that the conflation hides. Every defense the industry built after the npm attacks is aimed at package registries. Lockfile pinning, provenance attestations, install-script hardening, release cooldowns, Trusted Publishing with short-lived OIDC tokens instead of long-lived secrets on dev machines. All of it assumes the dangerous artifact arrives through npm install.

The attacker in May 2026 didn’t use npm install. They used the IDE extension marketplace, which is a software supply chain that almost nobody treats like one.

Walk the chain and notice how each hop defeats a different assumption. Hop one stole credentials through a poisoned npm package, the channel everyone now watches. Hop two used those credentials to publish through the VS Code marketplace, a channel that auto-updates by default, runs extensions with your full user privileges, and gets a fraction of the scrutiny npm now gets. Hop three turned a single developer’s laptop into an enterprise breach, because that laptop held tokens into GitHub’s own systems.

The cleverest detail is in hop two. Per the GHSA advisory, the extension looked and behaved normally, then on activation ran a single shell command that downloaded its hidden payload from a planted commit on the legitimate nrwl/nx GitHub repository. The malware-hosting URL pointed at the real vendor repo. That defeats the “is this from the official source?” check that a careful engineer would actually run. The provenance was genuine. The artifact was not.

What the numbers actually show

Install telemetry undercounts this badly, and it’s worth understanding why before you decide it didn’t reach you. Microsoft’s initial figure was 28 installs during the window. Nx’s CEO Jeff Cross stated actual activations likely exceeded roughly 6,000, against an extension with 2.2 million-plus total installations. The gap between 28 and 6,000 looks like the difference between fresh installs and an auto-updating base quietly pulling the bad version. Reporting confirms both figures but doesn’t explain the gap, so read that as the most likely mechanism, not a stated finding.

And the downstream number is the one that should reframe how you think about “small” supply-chain incidents: roughly 3,800 of GitHub’s internal repositories copied via a single compromised employee device, with reporting also naming OpenAI and Grafana among the affected. “Minutes live” and “small install count” do not bound the impact when the victims are high-value developers holding privileged tokens. An 18-minute window is plenty when one of the people who walks through it works at GitHub.

The payload reflects the same shift. Per the GHSA advisory, the harvester pulled from disk and memory: GitHub and npm tokens, AWS instance credentials, SSH private keys, HashiCorp Vault tokens, 1Password data, database connection strings, and Anthropic Claude Code configuration. That last one is the tell. AI-tooling config is now an explicit harvest target, not just a recon helper as it was in 2025. Exfiltration ran over HTTPS, the GitHub API, and DNS, so blocking one egress path doesn’t close the door.

A note on confidence, because it changes how you act. Threat-actor attribution is not firmly established; some reporting references a “TeamPCP” handle, but treat that as unconfirmed. CISA tagged the CVE for known ransomware-campaign use, but no source reviewed names the group or a completed deployment. The practical implication holds regardless: the ransomware tag is the signal to treat any v18.95.0 exposure as incident response, not patch hygiene.

What this means for prioritization

If you ran Nx Console v18.95.0 between roughly 12:30 and 12:48 UTC on May 18, this is not a “patch it next window” item. The federal remediation deadline is 2026-06-10, about 14 days from the KEV add date, and the ransomware tag means you should treat the deadline as the outer bound, not the target.

DecisionAction
Was I exposed?If you can’t prove you never ran v18.95.0 on May 18, treat rotation as mandatory, not optional.
PatchRemove v18.95.0, install v18.100.0 or later from the official source. v18.95.0 is the only malicious release.
RotateEvery credential reachable from that machine: GitHub PATs and OAuth tokens, npm tokens, SSH keys, AWS keys, Vault tokens, 1Password items, .env and connection strings, and AI-tool tokens. Assume anything the user could touch is burned.
HuntPer GHSA, terminate __DAEMONIZED and cat.py processes and remove the persistence artifacts listed for Windows, macOS, and Linux.
AuditCheck the GitHub audit log, AWS CloudTrail, npm, and 1Password activity in the post-install window.
High-sensitivity machinesCI runners and anything holding cloud-admin creds: reimage rather than clean in place.

Treat the GHSA artifact list as authoritative. Some of the more exotic IOCs floating around (specific kitty-prefixed paths, a bun.exe autostart entry, the orphan commit hash) are single- or dual-source from StepSecurity and Aikido; they’re useful hunt leads, not gospel.

What to watch

The lockfile-pinning analog for extensions is to pin extension versions and disable auto-update on high-trust machines, because VS Code auto-updates by default and that default is exactly what let a 6,000-activation event hide behind a 28-install number. The open question is whether the ecosystem treats this as a marketplace problem or keeps filing it under “npm again.” Watch where the next one lands. If the registries get cooldowns and provenance gates while the extension marketplaces stay wide open, the attackers have already shown which door they’ll use. Tracking which CVEs are actually being exploited, separated from the ones that just score high, is the daily job at PatchDay Alert.

One last thing. The seven days between the TanStack token theft on May 11 and the extension publish on May 18 haven’t been explained in public reporting. A week is a long time to sit on a working GitHub token. It either means the attacker was building the extension payload, or it means they were choosing the door. Neither is comforting.

Sources

Share

Related field notes

Get the free CVE triage cheat sheet

Subscribe and we'll email you the one-page triage flow for fresh CVEs. Plus the weekday digest.

Subscribe