PSA: That Pinned Plugin Backdoor Hit 4 Coding Agents, Check Yours Now

The pinned plugin backdoor affected 4 coding agents, and one of mine had the plugin enabled when I checked its configuration. What should I inspect to determine whether it executed or exposed credentials? I’ve reviewed 7 configuration files and disabled the plugin, but which logs, caches, or tokens require verification or rotation?

Don’t wipe the agent directories or reinstall everything yet. That can destroy the best evidence. First copy the configuration, plugin files, agent logs, shell history, temporary directories, and relevant file timestamps. Check for child processes, unexpected commands, persistence files, outbound connections, and downloads created while the plugin was enabled. Proxy, DNS, firewall, EDR, and cloud audit logs are often more useful than the agent’s own logs.

Treat any secret the agent could read as potentially exposed, including environment variables, API keys in config files, Git credentials, SSH keys, package registry tokens, cloud credentials, CI secrets, and cached browser or CLI sessions. Review provider-side usage for unfamiliar IPs, new keys, repository access, permission changes, and unusual API calls. Don’t forget credentials embedded in prompts, terminal output, transcripts, or workspace files.

Revoke active sessions and rotate short-lived or easily replaced tokens first. Replace higher-impact keys if execution is confirmed, network history is missing, or you cannot establish when the plugin became active. Disablement stops future use, but it does not invalidate anything already copied. Keep a timeline of installation, activation, agent runs, and rotation times so later audit events can be matched against the exposure window.

Being enabled is not a state of execution so the config toggle is essentially useless, check the plugin cache for the artifacts hash plus the install, update and load times and check the agent event logs for any tool registration or invocation. But most importantly determine what the plugin process could potentially access on the host: environment variables, mounted homedirs, credential helpers, docker-sock, cloud-metadata endpoints, anything that exposes credentials. This will give you an idea of what credentials should be rotated even if the plugin didn’t explicitly print them out in readable form

Don’t treat the agent’s own logs as authoritative. @vibergirl is right about mapping access, but check the other end too: cloud audit logs, Git provider token activity, package registry access, secret-manager reads, DNS/proxy records, and CI job history. Look for use from unfamiliar IPs, new keys, permission changes, or access outside normal hours. Those records may survive even if the plugin deleted local evidence. If a credential was readable but has no reliable usage logging, assume exposure and rotate it.

Check both sides of the execution boundary. Many coding agents keep the plugin on your host, while executing generated commands in a container, VM or remote runner, so only inspecting the workspace is unlikely to capture the true compromise.

I’d contrast these as follows:

  • Host process: plugin install/load hooks, child processes, keychain access, SSH agent sockets, cloud CLI caches, and outbound traffic.
  • Execution environment: mounted secrets, injected environment variables, Docker socket access, filesystem changes, and network requests.
  • Remote services: repository, CI, cloud, registry, and secret-manager audit events.

I would go slightly further than “enabled isn’t executed”, because a plugin can be executed at installation, update, agent startup, or registration to a tool, not necessarily tied to an actionable user-invoked event. You can build the time window of exposure based on all of these events and correlate them with the timestamps in the host, container, and provider-specific logs. This would tell you what set of credentials was actually exposed and not force a rotation of everything blindly.

You probably won’t get a clean yes or no from the agent logs. Assume the current workspace may be part of the evidence, not a safe place to keep working.

Don’t run the project’s normal build, test, install, or startup commands until you inspect them. A malicious plugin does not need to send credentials out immediately. It can alter a package script, Makefile, task definition, Git hook, CI workflow, container entrypoint, or IDE launch configuration so the theft happens the next time someone uses the repo. That delayed path is easy to miss if you only search for network traffic during the plugin’s active period.

Compare the workspace with a known-good commit from a separate machine. Include untracked and ignored files, not just the output of a basic git diff. Check .git/hooks, the reflog, stashes, extra branches, remotes, submodule URLs, global and local Git config, package-manager configuration, shell startup files, editor tasks, Docker files, and CI definitions. Review dependency and lockfile changes carefully. A tiny lifecycle script buried in a dependency update can matter more than an obvious new executable.

@digital_circuit is right about separating the host from the runner, but apply that separation to the repository too. A compromised host might leave the runner untouched while planting a change that CI executes later with much better credentials. Inspect recent CI runs for unexpected workflow edits, reruns, artifact uploads, changed environment handling, or jobs triggered from branches nobody recognizes. Cancel queued jobs from the affected repository until those files have been checked.

Do the inspection from a clean system or a read-only copy if possible. Searching the suspect machine with its own shell, language runtime, or project tooling can execute modified startup code. Hash the copy first, preserve the original, and record exactly what commands you use. If you find a planted hook or workflow, treat every secret available to the process that eventually ran it as exposed, even if the original plugin process never had direct access to that secret.

Realistic expectation first: for most single setups you are never going to get a clean answer on whether it ran. The kind of forensic depth people are talking about here assumes you have proxy logs, EDR, and cloud audit trails lying around. Plenty of us don’t. If your whole record is the agent’s own log and your shell history, well, you’re working blind and no amount of timestamp correlations can fix missing data.

Which is why I’d flip the decision. Instead of trying to prove execution and then rotating, sort your secrets by how painful they are to rotate. Anything cheap to cycle (API tokens, registry tokens, session cookies) just rotate now and stop agonizing over it. The expensive ones, cloud root-ish keys, signing keys, anything wired into a dozen services, are where the careful reachability check @anna_nerd described actually earns its keep. Spending an afternoon on forensics to avoid a thirty second token rotation is backwards.

The point I’d genuinely hold onto from above is @socket.ml on the delayed payload. That one bites people because they check for outbound traffic during the plugin window, see nothing, and call it clean. A modified pre-commit hook or lockfile entry doesn’t phone home until you run the project again. So even if you decide the machine is probably fine, don’t run the build on it before you’ve diffed against a known-good copy. That’s the trap, not the exotic keychain stuff.

Realistically, you may only be able to bound the exposure, not prove exactly what ran. Check the coding agent’s own account or team control plane, not just the machine: synced settings, remote workspaces, transcript uploads, plugin deployment history, active sessions, and organization-wide configuration changes. A plugin could use the agent’s normal network channel, so its traffic may look legitimate in DNS or firewall logs.

Preserve those records before removing the plugin or leaving the organization, since cleanup can change timestamps or make account history harder to retrieve. Then compare every agent sharing that account, config sync, or workspace. The affected machine may not be the only place where the plugin was loaded.