RESEARCHNew from Trench Labs: How Trench Stopped an Agentic Supply Chain Attack Before It SpreadRead Research
BLOGRead our latest blog post: Trench Agentic SecOps: Skills vs. PlaybooksRead Article
AWARDAnnouncement: Trench Security is the 2026 Winner of ‘Products That Count’Read the Announcement
RESEARCHNew from Trench Labs: How Trench Stopped an Agentic Supply Chain Attack Before It SpreadRead Research
BLOGRead our latest blog post: Trench Agentic SecOps: Skills vs. PlaybooksRead Article
AWARDAnnouncement: Trench Security is the 2026 Winner of ‘Products That Count’Read the Announcement
RESEARCHNew from Trench Labs: How Trench Stopped an Agentic Supply Chain Attack Before It SpreadRead Research
BLOGRead our latest blog post: Trench Agentic SecOps: Skills vs. PlaybooksRead Article
AWARDAnnouncement: Trench Security is the 2026 Winner of ‘Products That Count’Read the Announcement
Research

How Trench Stopped an Agentic Supply Chain Attack Before It Spread

Hari Prasath Selvan
Hari Prasath Selvan
AI Security Researcher
September 15, 2026 6 min read
How Trench Stopped an Agentic Supply Chain Attack Before It Spread

A worm built to steal, move, and republish itself needed no human attacker at any stage. Trench caught it before the chain could run.

Every development team trusts a stack of third-party tools without a second thought: the scanner that checks Terraform files for misconfigurations, the extension that speeds up code review, the base image everyone pulls without reading the changelog. That trust is the whole point of a supply chain. It is also, increasingly, the whole target.

On April 22, 2026, security researchers at Socket disclosed a compromise across multiple Checkmarx distribution channels: the official checkmarx/kics Docker Hub repository, and two VS Code extensions, cx-dev-assist and ast-results. Attackers with valid Checkmarx publisher credentials pushed trojanized images and extension versions through legitimate publishing flows. Docker's internal monitoring caught the Docker Hub side within roughly ninety minutes. The extension compromise had a longer runway.

Trench Security runs continuous threat intelligence correlation across our client environments. When the disclosure went public, that correlation surfaced exposure across our client environments: Checkmarx KICS Docker images and extension versions had been pulled into local development and CI/CD tooling within the exposure window, on a small number of developer machines. We isolated the affected workspaces, revoked and rotated every credential those accounts held, and purged the compromised artifacts before the later stages of the attack had a chance to fire. Our review of outbound traffic, source-control audit logs, and package publish history found no evidence that data left any environment.

This post covers three things: what the public disclosure describes, what actually happened, and, because the honest answer to "how bad could this have gotten" is worth publishing, a walkthrough of the attack chain that never got to run.

The pattern behind this class of attack#

Before the specifics, it helps to see the shape of the attack on its own, apart from any one incident:

Supply chain compromise: the pattern behind this class of attack

A trusted developer tool is quietly weaponized. Every later step runs on its own.

What the disclosure describes#

Socket's investigation, prompted by an alert from Docker, traced the compromise to a backdated commit in the Checkmarx AST VS Code extension repository carrying a roughly 10MB obfuscated payload, mcpAddon.js, made to look like a 2022-era change. The two affected extensions, cx-dev-assist (versions 1.17.0 and 1.19.0) and ast-results (versions 2.63.0 and 2.66.0), silently downloaded and executed the addon through the Bun runtime with no user confirmation or integrity check. The behavior briefly disappeared in v1.18.0 before returning. On the Docker Hub side, a threat actor authenticated with valid Checkmarx publisher credentials and pushed malicious images to the checkmarx/kics repository on April 22, 2026, overwriting the v2.1.20, alpine, debian, and latest tags and introducing a rogue v2.1.21 tag with no legitimate upstream release behind it.

Once running, mcpAddon.js harvested GitHub tokens, cloud credentials across AWS, Azure, and GCP, npm configuration, SSH keys, environment variables, and local Claude and MCP configuration files, then exfiltrated everything to a lookalike endpoint, audit.checkmarx[.]cx, built to resemble real Checkmarx infrastructure. Stolen tokens were then used to find repositories with configured secrets and drop a workflow file that exfiltrated those secrets as build artifacts. Stolen registry credentials were used to republish trojanized packages under the victim's own name. A group calling itself TeamPCP has claimed responsibility, and researchers note the technique is consistent with an earlier March 2026 campaign from the same group against Checkmarx GitHub Actions and OpenVSX plugins, alongside Trivy and LiteLLM.

Read the sequence again and notice what is missing: at no point does a human operator need to be at a keyboard. Credential theft, lateral movement, and propagation are all pre-scripted. That is not incidental to this attack. It is the design.

What TASC found#

A public disclosure like Socket's arrives as unstructured advisory text: repository names, tag versions, file hashes, an exfiltration domain. Turning that into "does this affect us, and where" is normally a manual pivot across a SIEM, a package registry, and a CI/CD system, worked by an analyst who has to read the writeup, extract the indicators, and go hunting by hand.

How Trench closes the gap: from a public disclosure to a closed loop

Correlation, scoping, and containment run as one motion, not five separate handoffs.

Trench Agent Semantic Context (TASC), the semantic layer we introduced in The Agent Is Not the Product. The Foundation Is., is built to remove that pivot. It reads a disclosure the way an analyst would and maps it directly onto the entities already known inside the environment: developer accounts, image pulls, extension installs, without a human translating threat intel into a query first.

That correlation returned a short, specific list of affected accounts inside the exposure window. Getting a short list rather than "check everyone" came down to Signal Memory: Trench had already built a behavioral baseline of which accounts routinely pull which images and install which extensions, so matching the disclosed indicators against that baseline narrowed a company-wide search to a handful of named machines in minutes rather than days. Intent Graph did the harder part of the work: mapping what each affected account could actually reach, which repositories, which CI/CD secrets, which downstream packages, so containment was a specific, bounded action rather than a guess about scope.

This is the same argument for velocity we made in Launching Trench Agentic Threat Detection Mesh: the gap between a public disclosure and internal correlation is where most of the real damage in a supply chain compromise happens. Zero latency threat detection is not a figure of speech here. It is the difference between a handful of accounts and dozens.

What we did about it#

The affected accounts, once identified, moved through containment as a single closed loop rather than a checklist worked by hand. Affected developer workspaces were isolated from the network to cut off any live credential harvesting or outbound connection. Every active token those accounts held, source-control, package registry, and cloud provider credentials, was revoked and rotated. The compromised Docker images and extension versions were purged from every local environment where they turned up. We then reviewed package publish history for unauthorized releases from the affected accounts and outbound network logs for connections to the known exfiltration endpoint. Neither turned up anything.

None of that required a human to log into five consoles and stitch a story together by hand. That is the difference between Actionable SecOps and a well-organized alert: the finding arrived already scoped, with the response already run, rather than a ticket waiting for someone to start on it. It is Headless SecOps in the most literal sense available: nobody needed to open a dashboard to know the affected accounts were exposed, contained, and clean.

Our assessment is that exposure was real. The compromised artifacts were present on the affected machines. But containment landed before the credential-harvesting and propagation stages executed against them. We continue to monitor the affected accounts and their downstream repositories on our clients' behalf for delayed indicators.

How Trench stopped a supply chain attack before it spread

Caught before the attack chain fired: correlation, detection, and containment in one motion.

Recommendation: audit every third-party Docker image and extension source in developer tooling, and enforce signed, verified image policies before artifacts reach local environments or CI/CD pipelines.

The attack chain that never fired#

What follows is a hypothetical reconstruction, not a description of what happened in any specific client environment. We are publishing it because the disclosed behavior of mcpAddon.js gives an unusually precise picture of what containment actually prevented.

Had the compromised extension or image kept running past the point of containment, the publicly documented payload behavior maps out roughly this timeline:

  • Hours 0 to 1, silent credential harvest. GitHub tokens, cloud credentials, registry tokens, SSH keys, and any Claude or MCP configuration on the affected machines reach the attacker's collection endpoint before any user-visible symptom appears.
  • Hours 1 to 6, lateral movement through source control. Stolen tokens enumerate every repository the affected accounts can reach, find the ones with configured secrets, and drop a workflow built to dump those secrets on the next run, often minutes away in an active engineering org.
  • Day 1 to 2, registry propagation. Stolen credentials push trojanized versions of any package the affected accounts are authorized to publish, turning a handful of developer machines into a distribution point for the same payload.
  • Ongoing, self-hosted staging. Public repositories appear under the compromised accounts' own identities, auto-named, encoding stolen data in commit history. Visible in plain sight, easy to miss unless someone is specifically looking.
  • Blast radius. Because the payload's playbook is to republish to any registry the victim can reach, the realistic worst case is not limited to the accounts found. It is every internal and external consumer of anything those accounts had publish rights to, plus every pipeline that trusted secrets those repositories held.

The gap between that scenario and what we actually reported above is entirely a function of how early the exposure was found relative to when those later stages fire. That is the argument underneath AI Changed the Threat Landscape. Why Are We Still Defending Like It's 2020?: a worm built to run without a human attacker does not wait for a shift change or a Monday morning triage queue, so the defense on the other side cannot either.

Why this matters beyond one incident#

Notice what mcpAddon.js was built to steal alongside the usual developer credentials: Claude and MCP configuration files. That was not an afterthought. As development teams wire agents directly into their local tooling, source control, cloud consoles, package registries, an agent's own credentials and context have become as valuable to steal as a developer's SSH key, and in some environments more valuable, because an agent with write access can move faster than the person it works for.

The blind spot this family of attacks exploits: visible reasoning, invisible action

Signal Memory gives the action side a baseline. Intent Graph gives it a map.

There is a broader gap here, and it is not specific to this incident. Most environments log what an agent or a piece of tooling was asked long before they log what it actually did: prompts and completions arrive by default from the model platform, while tool invocations, credential use, and extension activations often have no single owner responsible for capturing them at all. The industry's own taxonomy for this is starting to reflect it: MITRE ATLAS now carries dedicated techniques for AI agent tool invocation and tool-based exfiltration, distinct from the prompt-level attacks the category started with. An environment that only sees what was asked, and not what was done, can reason about an agent perfectly and still miss the incident.

We made a version of this case in The Agent Is Not the Product. The Foundation Is.: agentic security has to start from a data foundation that understands the environment, not from bolting detection onto infrastructure built for human-paced attacks. This incident is that argument playing out in real client environments rather than a hypothetical one. Protecting an agentic enterprise means correlating threat intelligence against a developer's credentials and an agent's credentials with the same rigor, at the same speed, because the attacks aimed at both no longer wait for a human on either side of the exchange.

Details in this post are drawn from investigations across multiple client environments. They are not part of Socket's public disclosure. Client identities, account counts, and environment specifics are withheld or generalized throughout.

Know your exposure before the next disclosure lands.#

See what Trench correlates across your developer tooling, CI/CD pipelines, and agent credentials, automatically.

Talk to Trench →

Discussion (0)

No comments yet. Be the first to start the discussion!

SUBSCRIBE TO TRENCH DIGEST