Abusing a GitHub Codespaces Feature For Malware Delivery
Proof of Concept (POC): We investigate one of the GitHub Codespaces’ real-time code development and collaboration features that attackers can abuse for cloud-based trusted malware delivery. Once exploited, malicious actors can abuse legitimate GitHub accounts to create a malware file server.
GitHub Codespaces, initially in preview for specific users, became widely available for free in November 2022. This cloud-based integrated development environment (IDE) allows developers and organizations to customize projects via configuring dev container files, easing some previous pain points in project development.
We investigated the services offered by this cloud IDE and found that one of its features for code development and collaboration – sharing forwarded ports publicly – can be abused by malicious actors to create a malware file server using a legitimate GitHub account. In the process, these abused environments will not be flagged as malicious or suspicious even as it serves malicious content (such as scripts, malware, and ransomware, among others), and organizations may consider these events as benign or false positives.
According the GitHub’s website, they have over 94 million developers including companies like DuoLingo, Vanta, and GitHub themselves. And today, each developer can create at least two codespace instances for free. Considering this popular platform and the potential extensive use of Codespaces for ease in building, developers are strongly advised to properly secure their respective projects by applying threat modelling and testing.
What is GitHub Codespaces?
Among its features, GitHub Codespaces allows developers to share forwarded ports from the VM. Developers can share a forwarded port privately within the organization or publicly. A private port is only accessible to organization members via its URL, while anyone with the URL can view a publicly shared port without requiring authentication. This feature is helpful for developers who would like to see a preview of how an application would look like to an end user. At the same time, since GitHub Codespaces is now available for all GitHub users, this feature can be abused by cybercriminals and threat actors already on the platform.
If the application port is shared privately, browser cookies are used and required for authentication. However, if ports are shared with the public (that is, without authentication or authentication context), attackers can abuse this feature to host malicious content such as scripts and malware samples. Moreover, the barriers of costs in creating a Codespaces environment are now lower compared to creating a cloud service provider (CSP) account where you need a credit card to become a subscriber, be it in Azure, Amazon Web Services (AWS), Google Cloud Platform (GCP), and many others.
To validate our hypothesis of threat modeling abuse scenario, we ran a Python-based HTTP server on port 8080, forwarded and exposed the port publicly. In the process, we easily found the URL and the absence of cookies for authentication.
As seen from the image above, the exposed application domain URL has the following format:
GitHub Codespaces typically forwards ports using HTTP, but developers can change any port to HTTPS if needed. Once a developer updates a publicly visible port to HTTPS, the port’s visibility will automatically become private. A quick look at threat intelligence platforms like VirusTotal will show the domain having no malicious history, diminishing the chances of blocking the download of malicious files if distributed via this domain.
Automating the Creation of Open Directories
This section shows a simple script creating open directories on GitHub Codespaces as serving attacker-specified malicious content. For example, an attacker could repeatedly create a codespace with a publicly exposed port and use the same as a file server.
Using Dev Containers
Dev containers enable developers to use containers as full-featured development environments. One can run applications, including the tools, libraries, and runtimes required for the development. Using dev containers, the container setups can be reshared and reused. This aids in continuous integration, test automation, and full-featured coding environments.
The Dev Containers extension for Visual Studio Code enables developers to use a Docker container as a comprehensive development environment. By opening a folder within (or mounting it into) a container, developers can access all of it. In this scenario, the attacker’s dev container configuration may look as follows:
In this configuration, we forward the port 8000 using the forwardPorts property and run a Python-based HTTP server on each successful container startup using the postStartCommand property. The container image used is a devcontainer image maintained by Microsoft.
The attacker uses the GitHub CLI to authenticate the port using an access token and then creates a codespace instance using the following repository adititli/adititli, where the devcontainer.json configuration file is defined. After the codespace is deployed, the commands below are executed using the GitHub CLI inside the container.
The malicious files are downloaded inside the created codespace. Using the CLI again, we set the visibility of the exposed port to public. This essentially creates a webserver with an open directory serving the malicious files downloaded and waits for 100 seconds before deletion.
For our analysis and this proof of concept (PoC), the said 100 second duration can be modified. In general, the delay is used to remove the codespace after accessing the URL returned in the script.
Using such scripts, attackers can easily abuse GitHub Codespaces in serving malicious content at a rapid rate by exposing ports publicly on their codespace environments. Since each created codespace has a unique identifier to it, the subdomain associated is unique as well. This gives the attacker enough ground to create different instances of open directories. Additionally, codespaces can be retained for a maximum of 30 days, which implies that attackers can use the same URL for their operations in the said duration.
This analysis came about while investigating the platform from an adversarial security standpoint. It is essential to note that no abuse of this specific technique has been seen in the wild. However, cybercriminals have been exploiting free cloud platforms and services for fun and profit for a while now, ranging from CSPs’ free tiers to platform-as-a-service (PaaS) and software-as-a-service (SaaS) features such as Heroku, Google Drive, GitHub Actions, and many more. While the technique is not new, there have been a growing number of platforms and services seemingly being explored by these threat actors for targeting specific environments and malicious activities like cryptocurrency mining.
However, the difference lies in the abuse of legitimate accounts and domains. In the abuse we saw in GitHub/Netlify, the attacker stored the malicious samples on GitHub directly, wherein the IP address associated with the GitHub CDN (content delivery network) was already flagged as malicious, unlike in Codespaces. In a scenario abusing this POC, the attacker can manipulate the publicly shared port to infiltrate and deploy malicious content in a victim’s environment since the domain associated with the exposed port is unique and likely have never been flagged by security tools.
Cloud services offer advantages to legitimate users and attackers alike. It helps attackers scale their attacks quickly and easily, hide their tracks, and avoid detection by abusing legitimate services like GitHub Codespaces. The features offered to legitimate subscribers also become available to threat actors as they take advantage of the resources provided by the CSP. Developers must know the risks associated with GitHub Codespaces and take proper measures to secure their environments and accounts. To prevent future threats from abusing this platform to host known and unknown malware for infections and attacks, we recommend some best practices that IT and security teams can implement:
- Only use code that you can trust such as VSCode extensions and GitHub repositories, if possible. If not, developers should be aware of the repositories they are working on and should be careful while working with untrusted code. Malicious devcontainer configurations can put developments and environments at risk.
- Ensure that container images used in the devcontainer configuration are recognized and well-maintained. Threat actors have been observed performing typosquatting of popular container images on container registries.
- Use strong and unique passwords for GitHub, including carefully scoped tokens. Attackers may compromise existing accounts and create or access your Codespaces.
- Enable two factor authentication (2FA) to add an extra layer of security to accounts. Avoid committing secrets and credentials publicly as this can lead to credential leaks.
- Follow the best practices for implementing and using GitHub Codespaces identified in their official documentation.