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

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.
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.
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:
- Isolate the machine from the network via your EDR (CrowdStrike RTR, SentinelOne Remote Script). Do not ask the developer to do this manually.
- 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.
- Pull the VS Code extension logs from the machine before isolation if possible: ~/.vscode/extensions/[malicious-extension]/ and the VS Code developer console logs.
- 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.
- 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
Free resources
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.
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.
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.

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.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
