1 Introduction

Yesterday, I came across a Hacker News thread for a blog post that describes how to move all development tools to a virtual machine and only run the GUI of Visual Studio Code on the host. This setup is enabled by Microsoft’s Remote Development extensions that also let you run most extensions inside the VM instead of on the host.

However, there is one part about the post that stood out to me:

I do not have any command-line tools installed on the host machine and no transitive dependencies of those to worry about compromising the host. All my development tools and editor extensions are sandboxed in a virtual machine boundary. It’s not perfect security but a useful level of defense […]

The use of VS Code in this way actually breaks up most of the security boundary that can exist between host and VM: Malicious extensions or code running within the VM could use VS Code’s Remote Dev tooling to execute arbitrary code on the host. But as of writing this post, there’s only one comment in the Hacker News discussion that points out this issue.

2 Confusion over security boundaries

I can see how one might conclude that VS Code Remote Development offers a security boundary between the remote and local host, given that the Remove Development FAQ include text like

Some benefits of remote development include:
[…]
Separating developer environments to avoid conflicts, improve security, and speed up on-boarding.

I also got the wrong idea when first learning about them. But when taking a closer look, you’ll notice that the only other mentions of security in the FAQ are in relation to secure access and transport. Similarly, for Dev Containers the documentation only talks about securely browsing untrusted projects via the Workspace Trust settings that allow code execution only with explicit user consent.

3 Official statements and disclaimers

When looking around in GitHub issues, I found these comments by Microsoft employees and VS Code developers (emphasis added):

For VS Code remote, the VS Code server is in the same trust boundary as the VS Code client. That means that you should only connect to VS Code servers that you trust. So you should only connect to SSH machines that you trust and only create dev containers from definitions that you trust (i.e. you should not use dev containers as a sandbox).
[…]
For Remote SSH, we include the following notice in the extension README:
Only use Remote-SSH to connect to secure remote machines that you trust and that are owned by a party whom you trust. A compromised remote could use the VS Code Remote connection to execute code on your local machine.

— alexdima on Apr 29, 2022

The Security Note in the Remote SSH README remains.

As for Dev Containers (emphasis added):

[…] Dev containers are not designed as a security boundary and containers are not considered a security boundary in general (there appear to be security hardened container engines). The devcontainer.json can have a “initializeCommand” that will run on the host. The devcontainer.json can bind mount any folder, making it accessible from the container. We forward Git credentials, ssh-agent and gpg-agent sockets into the dev container for convenience.

— chrmarti on Dec 9, 2022

Using the Remote Development or Dev Container extensions can offer some security through obscurity, by relying on attackers not targeting these workflows. But as these extensions/workflows further increase in popularity, I think it’s safe to assume that attackers will increasingly take these kinds of environments into account.

4 Potential future improvements

An issue comment from February 2023 reads: “[…] Perhaps if someone from the VS Code team would provide a few links to any official channels where VS Code security topics are discussed, we could consider this issue good enough to close?”. However, the commenter received no response and I wasn’t able to find anything like they suggested.

There’s [Feature Request] Extension Permissions, Security Sandboxing & Update Management Proposal from 2018, which proposes the introduction of a permission model like those used by Chrome or Firefox. But it doesn’t seem to make any progress.

And the only relevant item on VS Code’s roadmap is “Explore sandboxing of extensions in both local and remote scenarios”, which has been there for years and still isn’t actively being worked on.

That’s essentially all relevant information I found. It leads me to believe that the chance of this situation improving any time soon is low.

Tangent: Marketplace issues

The above feature request contains a link to a blog post about issues with the extension marketplace:

  • To get the verified badge, all you need is a domain to setup a TXT record and host an HTTPS server. And domains are cheap.
  • VS Code just blindly trusts the contents of the package.json file for all the extension metadata, like the source repository.
  • The authors managed to increase the install count of an extension by repeatedly installing it in a docker container. This got them featured in the Trending section of VS Code’s Extension Marketplace Front Page. However, it seems Microsoft fixed it by removing the Trending category.

5 Better isolation

While it’s probably safe to assume that most devs won’t have to worry about being targeted by VM-escape exploits, limiting the data that’s accessible from the VM without the use of any exploits is likely worthwhile:

  1. Also move the VS Code GUI to the VM and do not run any dev tools on your host
  2. Configure a single directory to share with the VM. If folders, mounts, device, etc. of the host are shared with VMs by default, ensure you disable all of that1.
  3. Use a dedicated VM for each project.
  4. Share a separate folder with each VM, instead of using a single folder for all VMs
  5. Only share devices, like printers, with the VM that you actually need
  6. Consider limiting or disabling clipboard sharing to protect any passwords, API keys and other sensitive data
  7. Have a look at your hypervisor settings to see if I missed something

If you implement the above, you can be reasonably sure that most malicious dependency updates in one VM won’t affect projects in other VMs or data/credentials on your host.

If you want to additionally limit the chance of being impacted by vulnerabilities in the hypervisor, guest tools, etc., you’ll want to limit the available integration/interfaces between the host and the VM. For example:

  1. Disable emulation of as many devices as possible
  2. Consider disabling all sharing (e.g. for Parallels see isolation) between the host and the VM and use e.g. Magic Wormhole for file sharing, optionally with a local relay
  3. For heightened security requirements: do not use/install guest tools whatsoever

For an overview of the hypervisor attack surface and a history of bugs, see Virtualization from an attacker point-of-view by Synacktiv team members.

5.1 Touch ID to authorize copy and paste

One commenter suggests to ssh from the VM to the host to retrieve clipboard contents, but to limit the commands that can be executed via authorized_keys and additionally require Touch ID for each request to read/write the host clipboard. In another comment they wrote that allow more commands, which they filter via a script.

It seemed like a good idea, so I worked on a proof of concept for copy and pasting via SSH with Touch ID authorization.

Demo

6 Conclusion

While Visual Studio Code’s Remote Development and Dev Container extensions simplify workflows and ensure consistent development environments, Microsoft’s documentation lacks warnings about the limited isolation these tools provide – even when used with virtual or remote machines. As a result, many developers mistakenly expect robust security boundaries where none exist.

A more secure approach involves running all development tools inside the VM and deliberately limiting integrations such as file sharing, clipboard access, and device pass-through between the host and the VM. This strategy helps ensure that development environments remain isolated and secure, mitigating potential risks associated with unintended interactions between the host and the virtual machine.


Footnotes

  1. In Parallels on Mac, for example, selecting the “Software development” profile for a Windows VM configures Parallels to mount the Mac user folder in the Windows VM and vice versa. It is additionally configured to share all cloud folders and mount Mac volumes in the VM.↩︎