Over the past couple years, developers have been increasingly targeted by attackers, with dozens of events occurring. These bad actors are targeting devs with the tools they depend on to build code. Earlier this year, a threat actor recently distributed a backdoored version of a .NET development tool to deploy multiple malicious payloads, like a clipboard hijacker and a crypto miner.
Developers are an attractive target for cybercriminals, as they have access to the core intellectual property assets of a company: the source code. Compromising a single developer enables attackers to embed malicious code into a company’s products. If that product is then used by other companies, the malware can spread to their systems in a so-called supply chain attack.
Case study: A closer look at Visual Studio Code vulnerability
Let’s take a closer look at a new vulnerability that the Sonar research team discovered in one of the most popular IDEs: Visual Studio Code. It allowed attackers to craft malicious links that, once interacted with, would trick the IDE into executing unintended commands on the victim’s computer.
The vulnerability can be used to target developers that have the Visual Studio Code IDE installed. Upon clicking on a malicious link crafted by an attacker, victims are prompted to clone a Git repository in Visual Studio Code. This operation is genuine and part of the workflow of most users.
If the developer accepts this operation, attackers can execute arbitrary commands on the victim’s computer. Interestingly, Workspace Trust, a feature to harden the IDEs and reduce the risk of unintended commands being executed, is not strictly enforced here. If the last Visual Studio Code window with focus is trusted by the current workspace, this security feature will not have the expected effect.
Visual Studio Code is most commonly used as a stand-alone desktop application, thanks to Electron. This choice still allows some level of integration with the user’s operating system, for instance, by allowing applications to register custom URL protocol handlers. In the case of Visual Studio Code, vscode:// is registered, and vscode-insiders:// for the nightly builds (also called Insiders build). This feature is named Deep Links.
The IDE allows internal and external extensions to listen to such events and handle them by registering sub-handlers. The main listener will handle such OS-level events and redirect them to the right extension. With this design in mind, it is now possible to start looking for URL handlers in the core of Visual Studio Code. At that time, three were available: extensions/github-authentication and extensions/microsoft-authentication to authenticate with third-party services and obtain the resulting access tokens, and extensions/git to allow users to clone remote repositories.
Based on our previous experience reviewing vulnerabilities in developer tools, we knew that external invocations of version control tools are often riddled with argument injection bugs. And sure enough, we turned up an argument injection bug in the code we examined: the URL to clone the Git repository is fully controlled and concatenated into the external command line. If this URL starts with dashes, Git will understand it as an option instead of a positional argument.
Argument injection vulnerabilities are very interesting because they are all different and often imply some subtleties; this one is not an exception.
It’s important to note that Microsoft promptly addressed the issue we discovered by improving its validation on the URL of the Git repository to clone as part of the commit c5da533. The URL is parsed using Uri, an internal URI parser, to validate the scheme against a pre-established allow list. The rationale behind this change is that the argument injection bug can only happen if the prefix of the data is fully controlled, which won’t be possible if the scheme part of the URL has to be part of this list.
Conclusion
To recap, a vulnerability in one of the Visual Studio Code URL handlers could lead to the execution of arbitrary commands on the victim’s host. The exploitation technique discussed above can also be applied to any other argument injection on a git clone invocation. We urge all developers to upgrade their IDE to the latest version and to remain careful when opening foreign links.
But the issue goes well beyond Visual Studio Code. In addition to this instance, our security research team has also discovered vulnerabilities and unexpected behaviors in several other tools used by developers, which could have helped threat actors to launch a range of targeted attacks. These include package managers and Git integrations in terminals. When one of these tools is compromised, simple actions like opening an archive in a terminal or in a code editor can let attackers breach an entire system. This same scenario can impact a wide variety of important developer products.
The safety of these developer tools is crucial to prevent attackers from compromising the computer on which developers are working, as they could use this access to obtain sensitive information, alter source code, and further pivot into the company’s internal network.