PRACTITIONER GUIDE | SUPPLY CHAIN SECURITY
Practitioner GuideUpdated 13 min read

Malicious VS Code Extensions at Work: How Security Teams Detect, Block, and Respond

18 min
the poisoned Nx Console 18.95.0 VS Code extension was available on the marketplace before removal in the May 2026 TeamPCP attack
3,800
GitHub internal repositories accessed using credentials stolen via the malicious Nx Console extension
57M+
VS Code extensions downloaded monthly from the official marketplace, with no code signing requirement until 2024

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

The VS Code extension marketplace does not require cryptographic code signing from publishers, does not perform runtime behavior analysis before listing, and does not notify enterprises when a trusted extension is updated with new permissions or new code. An attacker who compromises a popular extension's publisher account, or creates a convincingly named lookalike, has direct code execution on every developer machine that installs it. The May 2026 attack used a poisoned Nx Console extension available for 18 minutes to steal credentials from developer machines and access 3,800 GitHub repositories.

Why VS Code Extensions Are a High-Value Attack Surface

VS Code extensions run with the full permissions of the user who launched VS Code. Unlike browser extensions, which are sandboxed and have a declared permissions model, VS Code extensions can read and write any file accessible to the user, make arbitrary network connections, spawn child processes, read environment variables including secrets, and access the git credential store.

An extension installed on a developer machine has access to:

  • Source code across all open workspaces
  • Environment variables including AWS_ACCESS_KEY_ID, GITHUB_TOKEN, and any secrets loaded by dotenv
  • The ~/.ssh directory including private keys
  • The ~/.aws/credentials file
  • Git configuration including stored credentials
  • Any secrets manager CLI credentials cached in memory

The attack surface is compounded by the fact that extensions auto-update silently by default. An extension that was benign when a developer installed it can deliver malicious code in a subsequent update without any user interaction.

Step 1: Audit Installed Extensions Fleet-Wide

VS Code stores installed extensions in a predictable location. On macOS and Linux: ~/.vscode/extensions/. On Windows: %USERPROFILE%.vscode\extensions. Each extension is a directory named publisher.extension-version.

For fleet-wide auditing, deploy a script via your MDM (Jamf, Intune, Workspace ONE) or configuration management tool (Ansible, Chef) that reads this directory on each machine and ships the list to a central location.

A simple audit script for macOS/Linux:

ls ~/.vscode/extensions/ | awk -F'-' '{NF-=1; print}' OFS='-' | sort -u

For Windows via PowerShell:

Get-ChildItem "$env:USERPROFILE\.vscode\extensions" -Directory | 
  Select-Object -ExpandProperty Name

Once you have the list, cross-reference it against your approved extension allowlist. Any extension not on the allowlist is a finding. Prioritize reviewing extensions with access to network (any extension that makes outbound requests) and extensions with access to the file system.

Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

Step 2: Block Unauthorized Extensions via Policy

VS Code supports an extensions.allowedExtensionIDs setting in managed configuration. When set, VS Code will only activate extensions in the allowlist, other installed extensions are disabled at launch.

Deploy this via your MDM as a managed VS Code configuration file. On macOS with Jamf, push a configuration profile that writes to /Library/Application Support/Code/User/settings.json (the machine-level settings file). On Windows with Intune, use a PowerShell script to write the setting to the machine-level settings path.

Example managed settings.json:

{
  "extensions.allowedExtensionIDs": [
    "ms-python.python",
    "ms-vscode.cpptools",
    "dbaeumer.vscode-eslint"
  ],
  "extensions.autoUpdate": false,
  "extensions.autoCheckUpdates": false
}

Disabling auto-updates (extensions.autoUpdate: false) is critical, it prevents silent malicious updates to approved extensions. Pair this with a review process for approving extension updates before pushing them to the managed allowlist.

Step 3: Detect Malicious Extension Behavior in EDR Telemetry

Even with allowlists, the detection layer matters. A compromised allowlisted extension needs to be caught at runtime. Look for these behavioral indicators in your EDR:

Unexpected outbound connections from Code Helper: On macOS, VS Code extensions run in the Code Helper (Plugin) process. Alert on outbound connections from this process to non-approved destinations, especially newly registered domains, residential proxy networks, or cloud storage endpoints not in your approved list.

File access outside the workspace: Extensions operating normally access files within the workspace root. Alert on Code Helper reading ~/.ssh/, ~/.aws/credentials, ~/.npmrc, or ~/.gitconfig outside of a workspace directory.

Child process spawning: Some extensions legitimately spawn child processes (linters, formatters), but alert when Code Helper spawns processes that make outbound network connections, especially curl, wget, python, or node executing scripts from temp directories.

Environment variable enumeration: An extension reading the full process environment (all variables) rather than a specific known variable is a behavioral anomaly. Some EDR platforms (CrowdStrike, SentinelOne) can detect this via API call monitoring.

Step 4: Respond When a Malicious Extension Gets Through

If you identify a malicious extension on a developer machine, treat it as a full credential compromise. The extension had code execution; assume everything accessible to that user's session is compromised.

Immediate actions in order:

  1. Isolate the machine from the network via your EDR (CrowdStrike RTR, SentinelOne Remote Script). Do not ask the developer to do this manually.
  2. Revoke all cloud credentials that could have been accessed: AWS IAM access keys and session tokens, GitHub PATs and SSH keys, npm tokens, any secrets in environment variables.
  3. Pull the VS Code extension logs from the machine before isolation if possible: ~/.vscode/extensions/[malicious-extension]/ and the VS Code developer console logs.
  4. Check what the extension had access to: the git log of every repository open in VS Code at the time, the list of workspace folders, and the environment variables in the user's shell profile.
  5. Review your extension allowlist and determine how the malicious extension was present, whether it was on the allowlist, whether it was a compromised update of an allowlisted extension, or whether the allowlist control was not yet enforced on this machine.

Building a Sustainable Extension Security Program

A one-time audit does not scale. The controls that keep extension risk manageable over time:

Extension change monitoring: Deploy a daily cron job on developer machines that diffs the current extension list against the last known state and alerts on new additions. A new extension appearing on a machine that is not in the managed configuration is an immediate finding.

Supplier monitoring for approved extensions: Subscribe to security advisories for every extension on your allowlist. The VS Code marketplace does not have an API for security advisories, but most popular extensions have GitHub repositories, watch their release notes and the VS Code marketplace publisher account for unexpected activity.

Extension publisher verification: Before approving a new extension, check the publisher's GitHub profile age, the extension's source code repository (many extensions do not publish source), the extension's install count history (a sudden spike in installs of a previously unknown extension is a red flag), and whether the publisher account was recently transferred.

The bottom line

VS Code extensions have code execution on your developer machines and silent auto-update enabled by default. The allowlist control and auto-update disable are the two changes that immediately reduce your exposure. Deploy them via MDM before your next developer onboards, retrofitting security controls after a compromise is harder than preventing the first one.

Frequently asked questions

Does the VS Code marketplace scan extensions for malware?

Microsoft runs automated scanning on marketplace submissions, but it is not comprehensive enough to catch sophisticated malicious code. Extensions are not code-signed in a way that prevents publisher account compromise from delivering malicious updates. Microsoft added extension signing in 2023, which provides some tamper detection for extensions that opt in, but does not prevent a legitimate publisher account from submitting malicious code.

Can VS Code extensions access environment variables and secrets?

Yes, fully. VS Code extensions run as Node.js processes in the same user context as VS Code itself and have access to all environment variables, the file system, and the ability to spawn child processes. There is no sandbox preventing access to ~/.ssh/, ~/.aws/credentials, ~/.npmrc, or any other credential storage.

What is the extensions.allowedExtensionIDs setting and how do I enforce it?

This VS Code setting restricts which extensions can activate. Extensions not on the list are installed but disabled. It must be set in the machine-level settings.json (not user-level) and pushed via MDM or configuration management to be effective, if developers can modify their own settings.json, the control is bypassable.

How do I tell if a VS Code extension is making outbound network connections?

Use your EDR to monitor outbound connections from the Code Helper process on macOS or Code.exe on Windows. You can also use Little Snitch (macOS) or Windows Firewall with Advanced Logging to capture all outbound connections per process. Any connection from the extension host to a destination not in your approved list during a coding session is worth investigating.

Should I disable VS Code extension auto-updates for all developers?

Yes, in enterprise environments. Auto-updates allow a compromised publisher to deliver malicious code to every machine that has the extension installed. Pair the disable with a managed update process: review extension updates before pushing them to your allowlist configuration, then push the updated allowlist via MDM.

How do I verify that a VS Code extension allowlist is actually being enforced on a developer machine?

Open VS Code on the managed machine and attempt to install an extension that is not on your allowlist. If the allowlist is enforced via the machine-level settings.json, VS Code will display an error stating the extension is not allowed by the administrator. You can also inspect the effective settings by running the VS Code command palette entry 'Preferences: Open Settings (JSON)' and checking whether extensions.allowedExtensionIDs is populated with your managed list. If a developer can modify that value and re-enable blocked extensions, the machine-level settings.json path is not being written correctly -- confirm your MDM profile is targeting the machine scope, not the user scope.

Sources & references

  1. VS Code Extension Marketplace security policies
  2. Microsoft extension signing announcement
  3. TanStack supply chain attack, Decryption Digest

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.