IDE Extensions: The Ones That Actually Help, Settings Sync and Extension Security
An extension runs with your permissions and Workspace Trust can't stop it; Restricted Mode only stops a repo you don't trust from running code on its own. We read VS Code's built-in extension manifests with a .NET 10 file-based app and show why Git and TypeScript shut down in an untrusted workspace; a short, justified extension list, .vscode/extensions.json, Settings Sync, extensions.allowed and lessons from Marketplace incidents.
Version note: The code in this post was built and run with .NET 10 SDK (Software Development Kit) 10.0.402; the extension manifest analysis was done on the built-in extensions that ship in the application bundle of Visual Studio Code (VS Code) 1.145.2 on this machine. To avoid touching the user's VS Code profile, no extensions were installed and no settings were changed. The Visual Studio 2026 and Rider 2026.2 side comes from the official documentation; the malicious extension cases are summarized from Microsoft's Marketplace security post and from reports published by security firms.
Guess First
Someone on the Bookstore team installs a VS Code extension called "Angular snippets" with 40 thousand downloads. The extension seems to add only a few snippets. What do you think it can access on your machine: just the open file, the workspace, or everything your user account can reach (your SSH (Secure Shell) keys, the tokens in ~/.nuget, your browser profile)? And does VS Code's Restricted Mode, that is, Workspace Trust, protect you from this extension?
In this post we look at extensions from two sides: productivity (a short list that actually helps, syncing settings, a recommendation list shared with the team) and security (an extension's permissions, what Workspace Trust doesn't protect, enterprise restrictions).
An Extension Runs with Your Permissions
VS Code's "Extension runtime security" documentation is plain about it: the extension host has the same permissions as VS Code itself; an extension can read and write files, make network requests, run external processes and change workspace settings. Visual Studio extensions (VSIX (Visual Studio Extension) packages) and Rider plugins also run inside the IDE (Integrated Development Environment) process with the same user permissions. That is the first answer to Guess First: technically, the snippet extension can reach everything your user account can reach.
The answer to the second question is in the same document: Workspace Trust can't stop a malicious extension from running code and ignoring Restricted Mode. What Workspace Trust protects is something else: when you open a repo you don't trust, it stops the things inside that repo (tasks, debug configurations, workspace settings, scripts the terminal runs automatically, AI (Artificial Intelligence) agents) from running on their own. So there are two separate threat models: "bad repo" and "bad extension". Against the first you have Workspace Trust; against the second, only what you choose to install.
Workspace Trust: What Extensions Declare
Not every extension behaves the same in Restricted Mode. In its package.json, an extension declares with capabilities.untrustedWorkspaces.supported what it does in an untrusted workspace: true (works fully), false (is disabled) or "limited" (some features and settings are restricted). An extension that runs code and declares nothing is treated as false; code-less extensions such as themes and language grammars don't need trust. We read the declarations of VS Code's built-in extensions with the .NET 10 file-based app we saw in the previous post:
using System.Text.Json;
// reads extension manifests (package.json) under the given folder
string root = args[0];
Dictionary<string, int> counts = [];
foreach (string dir in Directory.GetDirectories(root).Order())
{
string manifest = Path.Combine(dir, "package.json");
if (!File.Exists(manifest))
{
continue;
}
using JsonDocument doc = JsonDocument.Parse(File.ReadAllText(manifest));
string support = "(not declared)";
if (doc.RootElement.TryGetProperty("capabilities", out JsonElement caps)
&& caps.TryGetProperty("untrustedWorkspaces", out JsonElement untrusted))
{
support = untrusted.GetProperty("supported").ToString();
}
counts[support] = counts.GetValueOrDefault(support) + 1;
if (support is "False" or "limited")
{
Console.WriteLine($"{Path.GetFileName(dir),-30} untrustedWorkspaces.supported = {support}");
}
}
Console.WriteLine();
foreach ((string support, int count) in counts.OrderByDescending(c => c.Value))
{
Console.WriteLine($"{support,-15} {count}");
}
$ dotnet run trust-report.cs -- "/Applications/Visual Studio Code.app/Contents/Resources/app/extensions"
git untrustedWorkspaces.supported = False
github-authentication untrustedWorkspaces.supported = limited
json-language-features untrustedWorkspaces.supported = limited
markdown-language-features untrustedWorkspaces.supported = limited
microsoft-authentication untrustedWorkspaces.supported = limited
ms-vscode.js-debug untrustedWorkspaces.supported = limited
npm untrustedWorkspaces.supported = limited
php-language-features untrustedWorkspaces.supported = limited
typescript-language-features untrustedWorkspaces.supported = False
(not declared) 63
True 23
limited 7
False 2
The table is instructive. Git and the TypeScript language service shut down completely in an untrusted repo: Git can run the repo's hooks and config; the TypeScript language service may load the TypeScript version from the workspace. The npm extension runs limited, because running package.json scripts means exactly running code from inside a repo. Of the 63 extensions that declare nothing, 60 are code-less packages such as themes and grammars; only three have an entry point. The Visual Studio counterpart is the security warning shown when you open a project downloaded from the internet; in Rider, the option to open an untrusted solution in "safe mode".
The Ones That Actually Help: A Short, Justified List
A good extension list is short, and every line has a reason. Rule: don't repeat with an extension what the IDE does built in. In Visual Studio and Rider most of the following are already inside; the list is mainly for VS Code.
| Need | VS Code | Visual Studio 2026 | Rider 2026.2 |
|---|---|---|---|
| C# language support, solution, tests | C# Dev Kit (ms-dotnettools.csdevkit) | Built in | Built in |
| Angular templates | Angular Language Service (angular.ng-template) | Angular Language Service extension (Microsoft) | Built in (WebStorm support) |
| Lint and format (TypeScript) | ESLint (dbaeumer.vscode-eslint), Prettier (esbenp.prettier-vscode) | Built-in ESLint support | Built in |
| .editorconfig | EditorConfig (editorconfig.editorconfig) | Built in | Built in |
| Containers | Container Tools (ms-azuretools.vscode-containers), Dev Containers | Container tooling in the NetWeb workload | Built-in Docker support |
| Seeing errors inline | Error Lens (usernamehw.errorlens) | Not needed | Not needed |
What isn't on the list is deliberate too: Git is built into VS Code and is enough for most teams; big extensions such as GitLens only for features you will really use. In Rider you don't need plugins that repeat ReSharper, and in Visual Studio you don't need AI extensions that repeat Copilot's built-in features. Every extension you add means startup time, memory and attack surface.
A Recommendation List in the Repo: .vscode/extensions.json
The team's extension decision belongs in the repo. When a workspace opens, VS Code shows the recommendations in .vscode/extensions.json; unwantedRecommendations stops recommendations for extensions the team doesn't want (in the example, an old formatter that conflicts with Prettier):
{
"recommendations": [
"ms-dotnettools.csdevkit",
"angular.ng-template",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"editorconfig.editorconfig"
],
"unwantedRecommendations": [
"hookyqr.beautify"
]
}
In the devcontainer.json from the sixth post, the same list is installed into the container automatically under customizations.vscode.extensions. The Visual Studio counterpart is the extensions section of the .vsconfig we saw in the second post. In Rider, plugins are a personal installation; we didn't find a direct equivalent of recommending plugins from the repo in Rider's documentation, so stating the plugins the team needs in the README is the simplest way.
Settings Sync, VS Settings Roaming and Rider Backup and Sync
Personal settings (theme, shortcuts, font) belong to your account, not the repo, and all three IDEs sync them to the cloud. VS Code's built-in Settings Sync carries settings, keybindings, snippets, tasks, UI (User Interface) state, extensions and profiles with a GitHub or Microsoft account; according to the docs it doesn't sync extensions to remote windows such as SSH, Dev Containers or WSL (Windows Subsystem for Linux). Visual Studio syncs theme, Fonts and Colors, shortcuts and Text Editor settings by default between machines signed in with the same personalization account; you turn it off under Tools > Options > Environment > Accounts. In Rider, the Backup and Sync plugin stores settings in your JetBrains account and carries them to every JetBrains IDE you sign in to with that account.
The distinction matters: team decisions live in the repo (.editorconfig, .vscode/settings.json, the team-shared .DotSettings), personal preferences in sync. Sync carrying a team setting that conflicts with the one in the repo is one source of "it looks different for me" conversations.
Restrictions in the Enterprise: extensions.allowed
Since VS Code 1.96, the extensions.allowed setting decides which extensions can be installed and enabled. Without it everything is allowed; with it, every extension that doesn't match the list is blocked and installed ones are disabled. Rules can be written at the publisher, extension ID, version and platform level:
"extensions.allowed": {
"microsoft": true,
"github": true,
"angular.ng-template": true,
"esbenp.prettier-vscode": true,
"dbaeumer.vscode-eslint": ["3.0.0"]
}
The microsoft publisher key covers all of Microsoft's extensions even if they use different publisher IDs. Version ranges aren't supported; every approved version is listed individually. Since users can change this setting themselves, the real tool in an enterprise is the AllowedExtensions policy: it is deployed through device management and overrides the user setting. The docs warn that if the policy value has a syntax error, the setting isn't applied at all; check the Window log. Since 1.97 VS Code also asks whether you trust a third-party publisher on the first install from it; when installing from the command line, the publisher is not trusted automatically.
Lessons from Marketplace Incidents
According to Microsoft's June 2025 Marketplace security post, the Marketplace scans every package with several antivirus engines before and after publishing, checks runtime behavior in a sandbox and signs all VS Code extensions; VS Code verifies the signature on install. According to the same post, by that point in the year 136 extensions had been reviewed for suspected malicious code and 110 removed. A malicious extension removed from the Marketplace is put on a block list in VS Code and automatically uninstalled from machines that have it.
There is another side to the picture. According to reports from security firms, from late 2025 a campaign named GlassWorm published extensions on Open VSX (the open-source extension registry run by the Eclipse Foundation), used by VS Code-compatible editors such as Cursor, that hid code in invisible Unicode characters; in January 2026 malicious updates were pushed to trusted extensions from a compromised publisher account; in a later wave, clean-looking extensions were turned malicious by later adding dependencies on harmful extensions. The lessons are the same whatever the source:
- Download counts and stars are not trust signals; a verified publisher (blue check), an open-source repo, active maintenance and real need are weighed together.
- An update to a trusted extension can also be harmful; that is why version pinning (a version list in
extensions.allowed) and control over automatic updates exist in the enterprise. - Trusting an extension pack or an extension with dependencies means trusting the publishers of the dependent extensions too; the docs say so explicitly.
- Different registries have different protections; a team using a VS Code fork should know whether its registry automatically removes taken-down extensions from machines.
In Production
Manage extensions like dependencies. Do the same review you do for NuGet and npm packages (who publishes it, when it was updated, how many people maintain it) for extensions too; they are also code running on your machine with your permissions.
Limit secrets on the developer machine. Since an extension can reach everything you can, don't keep long-lived tokens in plain files; short-lived credentials and the operating system's keychain shrink the attack surface.
Watch for abandoned extensions. An unmaintained extension can break with a new IDE version or receive a risky update when ownership changes hands. Visual Studio 2026's broad compatibility with 2022 extensions is good news, but "works" is not the same as "maintained".
Common Pitfalls
Treating Workspace Trust as extension security. Restricted Mode stops a bad repo from running on its own; it doesn't stop a bad extension.
Repeating a built-in feature with an extension. Two formatters format the same file differently; two lint extensions show the same error twice.
Putting personal extensions in recommendations. The recommendation list is a team decision; themes and personal productivity tools belong in your Settings Sync.
Distributing extensions.allowed only as a user setting. A user setting can be changed; enterprise restrictions are done with policy.
Not noticing that an abandoned extension broke with the current IDE. At the first odd behavior after an IDE update, try disabling extensions first; in VS Code, Extension Bisect does that for you.
A Small Experiment
★☆☆ List your installed extensions and write a one-sentence reason for each. Remove the ones without a reason; compare the IDE's startup time before and after.
★★☆ Run this post's trust-report.cs against a copy of your own extensions folder (in VS Code, the "Extensions: Open Extensions Folder" command in the Command Palette shows where extensions are installed). Which extensions run fully in an untrusted workspace, and do they run code?
★★★ Prepare a .vscode/extensions.json for your team and an extensions.allowed draft for enterprise use. Try the draft on a test machine: what happens when you try to install an extension that isn't on the list, and what happens to one that is already installed?
Extensions add capabilities to the IDE; AI assistants go one step further and write code and run commands inside the IDE. In the next post we cover Copilot agent mode, Rider's AI features and the rules for using these tools safely.