---
title: "Malicious VS Code Extensions Are the New Supply Chain Backdoor: What Developers Must Know"
author: "Renn Calloway"
category: "Attack Surface & Threat Modeling"
date: 2026-08-20T16:05:12.788Z
canonical: "https://agenticcyber.co/blog/malicious-vs-code-extensions-are-the-new-supply-chain-backdoor-what-developers-m"
---

# Malicious VS Code Extensions Are the New Supply Chain Backdoor: What Developers Must Know

![Dark terminal screen displaying lines of green programming code.](https://cdn.pixabay.com/photo/2015/06/24/15/45/code-820275_1280.jpg?w=1200&q=75)

We found the extension during a routine audit of a developer's machine after an unusual outbound connection showed up in network logs. The extension was called something close enough to a legitimate formatter that it had been installed without a second thought. It had 40,000 installs on the VS Code Marketplace, a five-star average, and it was quietly reading SSH keys on startup before posting them to a domain registered six weeks earlier. The developer had no idea. Neither did anyone else on the team.

Malicious VS Code extensions are not a theoretical threat. They are the current preferred vector for targeting developer workstations, and the attack surface is larger than most security teams account for. The VS Code Marketplace has over 60,000 extensions, minimal submission controls, and no mandatory code review. Extensions run with the privileges of the developer running VS Code - which on most machines means access to credentials, source code, SSH keys, cloud tokens, and everything else that makes a developer workstation a high-value target in a supply chain attack.

What follows is how the attack surface actually works, how the compromise chain operates, and what you can do about it before an extension audit becomes an incident postmortem.

## Understanding the VS Code Extension Attack Surface

  ![](https://images.unsplash.com/photo-1533709752211-118fcaf03312?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w4OTQwNjJ8MHwxfHNlYXJjaHwxfHx0ZWNobm9sb2d5JTIwZGlnaXRhbCUyMFVuZGVyc3RhbmRpbmclMjB0aGUlMjBWUyUyMENvZGUlMjBFeHRlbnNpb24lMjBBdHRhY2slMjBTdXJmYWNlfGVufDF8fHx8MTc4NzI0MjEwM3ww&ixlib=rb-4.1.0&q=75&w=960&auto=format)
  Photo by [Markus Spiske](https://unsplash.com/@markusspiske) on [Unsplash](https://unsplash.com)

Extensions cross three trust boundaries that, taken together, make them more dangerous than most third-party dependencies in your software supply chain.

The first is local filesystem access. Extensions can read and write files anywhere the user has access - not just the open workspace. An extension responding to VS Code's onDidChangeTextDocument event to provide real-time linting can, in the same execution context, traverse ~/.ssh, read ~/.aws/credentials, or pull from ~/.kube/config. The API that enables useful functionality does not scope access to the workspace directory.

The second is credential storage. Extensions can access VS Code's built-in secret storage and, more importantly, the operating system credential stores that surface environment variables, token files, and anything else a developer has configured for CLI tooling. If a developer is authenticated to AWS, GCP, or a private package registry in their shell environment, a running extension can see it.

The third is network egress. Extensions can make arbitrary HTTP requests. There is no outbound filtering or domain allowlisting at the VS Code layer. An extension that needs to call a language server can equally call an attacker-controlled endpoint.

The distinction between marketplace-listed and sideloaded extensions matters less than most teams assume. Marketplace presence creates confidence that is largely unearned. Microsoft performs some automated scanning, but there is no mandatory code review, no identity verification beyond a Microsoft account, and no behavioral sandbox that would catch an extension that phones home on first run. The install count shown on a marketplace page tells you how many people installed it - not whether it is safe.

The privilege escalation path is direct: extension runs with user privileges, accesses SSH keys or cloud credentials stored on the machine, exfiltrates them, and then either the attacker uses those credentials directly or the extension commits modified code to a repository that a CI/CD pipeline subsequently runs with elevated permissions. The developer machine is not the target. It is the entry point.

## Why Extensions Became the Preferred Supply Chain Vector

  ![](https://cdn.pixabay.com/photo/2018/06/17/20/35/chain-3481377_1280.jpg?w=960&q=75)
  Photo by [analogicus](https://pixabay.com/photos/chain-security-metal-iron-3481377/) on [Pixabay](https://pixabay.com)

The asymmetry here is worth naming explicitly. Most developers apply more scrutiny to a new npm package than to a new VS Code extension, even though extensions have substantially deeper system access than most dependencies. A package imported into an application runs in the process context of that application. An extension runs in VS Code's process, which is the developer's own session, with access to everything that session can touch.

The barrier to publishing a malicious extension is low. Marketplace submission requires a Microsoft account and a .vsix file. There is no identity verification, no behavioral sandbox, and no mandatory wait period that would allow community review. An attacker can register an account, publish an extension with a convincing name and description, and have it listed and installable within hours.

Typosquatting and naming confusion are the primary delivery mechanisms. We have tracked campaigns where extensions were named to closely mimic high-install legitimate tools - one character transposed in a popular formatter's name, or a modifier like "-Pro" or "-Enhanced" appended to an official extension's name. Developers installing quickly from command palette search results, or following a team wiki link that has drifted from the correct extension ID, are the primary targets. The VS Code Marketplace does not currently enforce namespace protection the way some package registries do, so publisher identity can be spoofed at the display name level even when the publisher ID differs.

The combination - trusted execution context, low submission bar, and naming confusion as a delivery vector - makes extensions a more efficient attack surface than most others in the developer toolchain.

## Audit Your Current Extension Inventory

The starting point is knowing what is installed. Open VS Code and run code --list-extensions from the terminal, or check .vscode/extensions.json for workspace-level recommendations. For team-wide audits, you want the output from every developer machine, not just your own - extension sprawl accumulates through years of individual decisions, and the long tail of rarely-used extensions is where exposure typically hides.

Cross-reference the list against your team's approved tooling inventory. If you do not have one, building it is the first step. Every extension that cannot be attributed to a specific team need is a candidate for removal.

For each extension that remains, pull its package.json from the installed directory (typically ~/.vscode/extensions/<extension-id>/package.json on Linux and macOS). Look at activationEvents. An extension that activates on * - meaning it runs on VS Code startup regardless of what you are doing - warrants scrutiny unless its function clearly requires it. Look at contributes.commands and any declared permissions. Look at whether it declares any extensionDependencies that are themselves unvetted.

Check the marketplace page for each extension. Is it still maintained? When was the last update? Has the publisher changed? An extension acquired by a new publisher after years of legitimate development is a known attack pattern - [researchers at Check Point](https://blog.checkpoint.com/) documented campaigns where attackers purchased dormant but widely-installed extensions and pushed malicious updates to their existing user base. Install count is not a safety signal; it is a measure of blast radius if the extension is compromised.

Remove anything unused. Reducing the installed set reduces the attack surface directly. For what remains, establish a review cadence - at minimum, quarterly checks that extensions are still maintained and that publisher accounts have not transferred.

## Enforce Extension Policies at the Team and Organizational Level

Individual audits are not enough. The process needs to operate at the team level, and ideally at the organizational level, to prevent new exposure from accumulating between audits.

VS Code supports workspace-level extension recommendations through .vscode/extensions.json, but recommendations are advisory - they do not prevent installation of other extensions. For harder controls, the VS Code for enterprise documentation covers policies configurable via Group Policy on Windows and MDM profiles on macOS and Linux. These can restrict which extension publisher IDs are permitted to install, which is allowlisting at the registry level rather than at the individual extension level.

Allowlisting and blocklisting are not equivalent. A blocklist requires you to know what is bad before you can block it. An allowlist requires you to know what is approved before anything else can run. For teams working on sensitive systems - anything touching production credentials, customer data, or critical infrastructure - allowlisting is the only approach that does not assume you will catch every malicious extension before it is installed. The operational overhead is real but manageable if the approval process is lightweight.

Build extension approval into your development workflow. When a developer wants to add a new extension to the team toolset, require a brief written justification: what problem does it solve, what alternatives were considered, and who is the publisher? Review the extension's source if it is open source. Check whether the publisher has a verifiable organizational identity. Add approved extensions to the workspace extensions.json and update your policy configuration. This does not need to be bureaucratic - for most teams, a Slack message with a link and a thumbs-up from a senior engineer plus a 15-minute review is sufficient. The value is in having a record and a default of explicit approval rather than implicit trust.

## Monitor Extension Behavior and Detect Anomalies

Normal extension behavior has a recognizable profile: file reads and writes within the open workspace, network calls to language servers, package registries, or the extension's own update endpoint, and terminal spawning for build tools or linters tied to specific file save events. What falls outside that profile is worth flagging.

Consider what the detection chain looks like in practice. An extension named something generic - a code formatter, a theme switcher - is installed and activates on startup. Within the first few seconds of VS Code launching, it reads ~/.ssh/id_rsa, constructs a POST request to a domain that resolves to an IP outside your expected geographic range, and exits without any visible behavior. Nothing in the VS Code UI reflects this. The developer opens their project and gets to work. The key is already gone.

Client-side monitoring can catch some of this. Process-level file access auditing on Linux (via auditd or eBPF tooling), Endpoint Detection and Response agents that log network connections by process, and DNS query logging at the network layer can all surface anomalous activity. But the limitations are real. An attacker who wants to avoid detection can exfiltrate slowly over DNS - encoding stolen credentials in query strings to a controlled nameserver generates traffic that looks like normal DNS resolution at most monitoring layers. They can trigger exfiltration only when specific files are opened rather than on startup. They can use VS Code's own telemetry infrastructure as a side channel if they are willing to be patient.

We do not have a clean solution to the detection problem that does not involve either sandboxing (which VS Code does not currently support at the extension level) or extremely restrictive network controls. What we do is run network egress filtering on developer machines that allows extensions to reach a known-good set of domains - package registries, cloud provider APIs, known language server endpoints - and alerts on everything else. That catches the obvious cases. It does not catch the sophisticated ones.

## Secure Your Development Environment Against Extension-Based Lateral Movement

The developer machine compromise is typically not the end goal. The goal is what the developer machine can reach.

The lateral movement chain operates like this: malicious extension steals git credentials or SSH keys from the developer machine, the attacker uses those credentials to push commits to a repository, the CI/CD pipeline clones and builds that code with elevated permissions, and the backdoor enters production. Alternatively, the extension modifies local build artifacts directly - injecting code into files the developer is actively working on before they are committed. The developer reviews a diff of their intentional changes and does not notice the injected lines in a dependency they did not touch.

Agentic development environments compound this risk. If you are running an AI-assisted coding agent - whether that is a hosted service or a custom agent built on top of an LLM - and that agent has access to the VS Code environment, a malicious extension can interact with the agent's context. It can inject content into files the agent reads, influence the suggestions the agent makes, or read the agent's memory and configuration. The attack surface expands because the agent is another process with privileged access to the workspace. We have written about prompt injection and context poisoning in agentic systems elsewhere on this site; the extension-to-agent attack chain is an instance of the same class of problem.

Practical isolation strategies: run agentic tools and AI coding assistants in a separate VS Code profile with a minimal and separately-audited extension set. Use Dev Containers or remote development environments for sensitive projects - the extension runs in the container context, not on your host machine, which limits what it can reach. Restrict network access from development containers to approved endpoints. If you are using a coding agent that maintains long-running state, treat that state as a potential poisoning target and audit its context as you would audit any other input to your pipeline.

Credential hygiene matters here independently of extension security: short-lived credentials, scoped API tokens, and SSH keys with passphrases all reduce the value of what an extension can steal. A 24-hour cloud provider token that is already expired when the attacker tries to use it is meaningless. Rotate credentials on a schedule that makes stolen long-lived tokens stale quickly.

## When to Escalate Extension Security Concerns

Some findings warrant more than a quiet uninstall and a note to be more careful next time.

If you discover an installed extension that has been acquired by a new publisher and you cannot verify the new publisher's identity, treat it as potentially compromised until you can establish otherwise. If you find evidence of an extension making network calls to unexpected endpoints - even if you cannot prove exfiltration occurred - assume credential exposure and act accordingly. If an extension update introduced new activationEvents or new network calls that were not present in a prior version, that is a meaningful signal.

Immediate response steps when you suspect compromise: isolate the affected machine from the network if you can do so without disrupting the investigation. Revoke any credentials that may have been exposed - API keys, SSH keys, cloud provider tokens, service account credentials. Revoke them all, not just the ones you can confirm were accessed. The cost of revoking an unnecessary credential is lower than the cost of leaving an active one in the hands of an attacker. Pull the extension's network traffic logs from your EDR or network monitoring if available and preserve them before any cleanup.

If the same extension was installed across multiple developer machines or across multiple organizations, this is a supply chain incident, not a workstation incident. Report it to [Microsoft's security team via the VS Code security disclosure process](https://github.com/microsoft/vscode/security). File a report with the Marketplace. Coordinate with your peers at other affected organizations if

## FAQ

### How do malicious VS Code extensions steal credentials without the developer noticing?

A malicious extension can activate on VS Code startup, read files like ~/.ssh/id_rsa or ~/.aws/credentials, and POST that data to an attacker-controlled domain - all within the first few seconds of VS Code launching and with nothing visible in the UI. The developer opens their project and gets to work while the key is already gone. Extensions have access to the local filesystem, OS credential stores, and can make arbitrary outbound HTTP requests with no built-in filtering at the VS Code layer.

### What should you check in a VS Code extension's package.json during a security audit?

Look at the activationEvents field - an extension that activates on '*' runs at VS Code startup regardless of what you are doing, which warrants scrutiny unless its function clearly requires it. Also review contributes.commands for declared permissions, and check extensionDependencies to see whether the extension pulls in other unvetted extensions. You can find the package.json in ~/.vscode/extensions/<extension-id>/package.json on Linux and macOS.

### Is a high install count on the VS Code Marketplace a reliable safety signal?

No. Install count tells you how many people installed an extension, not whether it is safe. Researchers at Check Point documented campaigns where attackers purchased dormant but widely-installed extensions and pushed malicious updates to their existing user base. A high install count actually increases the blast radius if the extension is compromised. The Marketplace performs some automated scanning but has no mandatory code review, no identity verification beyond a Microsoft account, and no behavioral sandbox.

### How can you enforce extension policies across a development team rather than relying on individual audits?

VS Code supports workspace-level extension recommendations through .vscode/extensions.json, but these are advisory only. For harder controls, VS Code for enterprise documentation covers policies configurable via Group Policy on Windows and MDM profiles on macOS and Linux, which can restrict which extension publisher IDs are permitted to install. An allowlist approach - where only explicitly approved extensions can run - is recommended for teams working on sensitive systems, since a blocklist requires you to know what is bad before you can block it.

### What steps should you take immediately if you suspect a VS Code extension has compromised a developer machine?

Isolate the affected machine from the network if you can do so without disrupting the investigation. Revoke all credentials that may have been exposed - API keys, SSH keys, cloud provider tokens, and service account credentials - not just the ones you can confirm were accessed. Pull the extension's network traffic logs from your EDR or network monitoring and preserve them before any cleanup. If the same extension was installed across multiple developer machines or organizations, treat it as a supply chain incident and report it to Microsoft's security team via the VS Code security disclosure process and file a report with the Marketplace.


---
Source: https://agenticcyber.co/blog/malicious-vs-code-extensions-are-the-new-supply-chain-backdoor-what-developers-m