A new vulnerability has been discovered that could allow an attacker to exploit a race condition within GitHub's repository creation and username renaming operations. This technique could be used to perform a Repojacking attack (hijacking popular repositories to distribute malicious code). This finding marks the fourth time a unique method was identified that could potentially bypass GitHub’s “Popular repository namespace retirement” mechanism. The vulnerability has been reported to GitHub and has been fixed.
- A novel vulnerability was discovered, exploiting a race condition between the processes of creating a repository and renaming a username on GitHub.
- Successful exploitation of this vulnerability impacts the open-source community by enabling the hijacking of over 4,000 code packages in languages such as Go, PHP, and Swift, as well as GitHub actions. Notably, hundreds of these packages have garnered over 1,000 stars, amplifying the potential impact on millions of users and a myriad of applications.
- The vulnerability has been responsibly disclosed to GitHub, which has subsequently issued a fix.
What is Repojacking?
Repojacking is a technique where an attacker takes control of a GitHub repository by exploiting a logical flaw that renders renamed users vulnerable.
The attacker hijacks a legitimate, often popular, namespace on GitHub. A namespace is the combination of the username and repo name, for example:
A namespace becomes potentially vulnerable to Repojacking when the original username is changed using GitHub’s “user rename” feature.
The change of username process is quick and straightforward. A warning lets you know that all traffic for the old repository's URL will be redirected to the new one.
In its documentation for this feature, GitHub mentions an important implication:
"After changing your username, your old username becomes available for anyone else to claim."
Once the username is renamed, an attacker can claim the old username, open a repo under the matching repo name, and hijack the namespace.
The "retired" Namespace Protection
To mitigate this potentially harmful behavior, GitHub put in place the “popular repository namespace retirement”protection measure: any repository with more than 100 clones at the time its user account is renamed is considered “retired” and cannot be used by others.
To clarify: what is considered “retired’ is the namespace, meaning the combination of the username and the repository name.
For example, let’s take the repository named “repo” of the username “account-takeover-victim.”
This repository was recently cloned 100 times, which qualifies it for the popular repository namespace retirement.
At this point, the account's owner decides to rename the username to whichever name they choose.
The practical result of this is that the username “account-takeover-victim” can now be claimed by anyone.
However, once the new owner of this username tries to open a new repository under the name “repo,” they will be blocked and get the following message:
This way, the old username is available for anyone to claim, but once this new username owner tries to create a new repository with a “retired” name, GitHub blocks this attempt.
Successful exploitation enables the takeover of popular code packages in several package managers, including “Packagist,” “Go,” “Swift,” and more. We have identified over 4,000 packages in those package managers using renamed usernames and are at risk of being vulnerable to this technique in case a new bypass is found. Of these packages at risk, hundreds of them have garnered over 1,000 stars on GitHub.
In addition, exploiting this bypass can also result in a takeover of popular GitHub actions, which are also consumed by specifying a GitHub namespace. Poisoning a popular GitHub action could lead to major Supply Chain attacks with significant repercussions.
Recent research by Aqua has revealed that organizations as large as Google and Lyft were vulnerable to this form of attack. This underscores the critical nature of the vulnerability, as it could potentially impact some of the biggest players in the tech industry, who have promptly mitigated the risks after being notified.
New Exploitation Method Bypassing the Retired Namespace Protection
The new exploitation method takes advantage of a potential race condition between the creation of a repository and the renaming of a username. Checkmarx SCS Group Architect, Elad Rapoport, has been able to demonstrate how he was able to bypass GitHub checks by almost simultaneously creating a repository and changing the username.
The steps to reproduce this exploit are as follows:
- Victim owns the namespace “victim_user/repo”
- Victim renames “victim_user” to “renamed_user.”
- The “victim_user/repo” repository is now retired.
- An attacker who owned the username “attacker_user” prepares a command which practically simultaneously creates a repo called "repo" and renames the username “attacker_user” to the victims also username, "victim_user". This is done using an API request for repository creation and a renamed request interception for the username change.
An example of the pseudo-exploitation command
This discovery marks the fourth time an alternate method has been identified for performing Repojacking. Checkmarx identified and reported bypasses to the "Popular repository namespace retirement" mechanism twice in 2022, both of which GitHub fixed.
Joren Vrancken, an external researcher, found a third bypass of this mechanism in 2022, which GitHub also addressed and fixed.
What can you do?
We recommend avoiding using retired namespaces to minimize the attack surface and ensuring that there are no dependencies in your code that lead to a GitHub repository vulnerable to RepoJacking.
Additionally, consider using ChainJacking (https://github.com/Checkmarx/chainjacking) which is an open-source project developed by Checkmarx, designed to help you realize if any of your Go lang direct GitHub dependencies is susceptible to the RepoJacking attack.
March 1st - 2023 - Checkmarx discovers an additional vulnerability to bypass the GitHub namespace retirement feature and discloses it to GitHub.
Sep 1st – 2023 - GitHub responds that they have fixed the bypass.
The discovery of this novel vulnerability in GitHub's repository creation and username renaming operations underlines the persistent risks associated with the "Popular repository namespace retirement" mechanism.
Many GitHub users, including users that control popular repositories and packages, choose to use the “User rename” feature GitHub offers. For that reason, the attempt to bypass the “Popular repository namespace retirement” remains an attractive attack point for supply chain attackers with the potential to cause substantial damages.
Moreover, it is interesting to notice that GitHub’s provided protection is activated based on internal metrics and gives the users no indication if a particular namespace is protected by it or not. This might leave some repositories and packages unknowingly at risk.
We recommend avoiding using retired namespaces and considering using our ChainJacking open-source project to identify vulnerable packages.
Our team continues to work diligently in identifying these vulnerabilities to ensure the safety of the open-source community. This vulnerability has been reported to GitHub.