string linking two chains together

GitHub patches flaw that allowed repojacking

A company’s defenses is only as strong as its weakest link. We’ve seen this time and again when cybercriminals take direct aim not at their target organization but at another company that is part of the target’s supply chain but with weaker defenses.

More often than not, one doesn’t have to be a l33t haxx0r to pull off a supply chain attack. Sometimes, all one needs is something uncomplicated, practical, and (to a degree) creative.

In the case of GitHub, a highly popular version control system (VCS) primarily used for code, attackers needed to just change a username.

This flaw is mindboggling in its simplicity, and it was discovered by the Supply Chain Security (SCS) team of Checkmarx, a cybersecurity company specializing in securing applications. In a recent report, the team revealed an attacker could hijack a GitHub repository by simply changing the GitHub username. Multiply this attack pattern by the thousands, and you’ve got yourself a trove of compromised project repositories potentially hosting malware that can be downloaded by millions of individuals and companies reliant on these projects.


Because a GitHub repository is tied to a username, which is tied to a user account, any changes to the username affect both. So what initially triggers the attack is the GitHub account owner changing their username. Of course, GitHub knows that renaming would cause a cascade effect, so it informs the account owner about this before finalizing their decision to rename.

(Source: Checkmarx)

Using a new name makes the user’s old name available for registration. This is what repojacking takes advantage of. An attacker can register the old username and populate its repository with rubbish files or malware. Once this happens, any redirects to the new username, including projects and dependencies referencing it, are disabled. Instead, redirects are routed to the repository under the old username which is under control of the attacker.

Repojacking is not a new way to hijack repositories. However, Checkmarx researchers found ways to bypass the protection GitHub put in place against repojacking. This latest bypass requires the abuse of GitHub’s “repository transfers” feature.

The bypass

The bypass is explained a lot more clearly in the form of an example.

Let’s say a GitHub namespace called “MWB/repo” exists. “MWB” is the username, and “repo” is the repository’s name.

GitHub has retired this namespace, meaning no one can use it anymore.

An account called “helpMWB” creates a repository called “repo”. The account owner then transfers ownership of the “repo” repository to a threat actor, who has an account called “fakeMWB”. But before accepting the transfer, the account owner of “fakeMWB” changes its username to “MWB”.

The new “MWB” account, which a threat actor controls, accepts ownership transfer of the “repo” repository. Thus, the once-retired “MWB/repo” is once again active.

Thankfully, GitHub has already fixed this flaw; thus, it’s no longer exploitable.

Mitigate against repojacking

In an interview with Security Innovation, GitHub said it has no plans to change how redirecting or username reuse works. This really isn’t the issue. While GitHub has a “popular repository namespace retirement” scheme, wherein re-registering a namespace with at least 100 clones in the days leading up to the account’s renaming or deletion is disallowed, the onus is on the developers to make sure the code they pull from GitHub are from safe and untainted locations.

Developers cannot fully guarantee their sources won’t cause them problems all the time. As such, a change in tactics might be in order.

  • Don’t link directly to GitHub repositories. Use a dedicated third-party package manager instead (GitHub is not one, although it has a Packages feature).
  • Use version pinning and a lock file. Most popular package managers support these implementations. Version pinning is tying a clean software version to a dependency or framework using SHA1 hashes. This way, attackers won’t be able to assign a malicious software version to a dependency. A lock file, on the other hand, is a file containing all version-pinned dependencies. It’s “a single source of truth” for anyone who wants to build on a project. However, skilled hackers can bypass version pinning and lock files on most package managers.
  • Download all project dependencies in your repository. This practice is known as vendoring. Doing this means you don’t have to link to another GitHub repository for your project. However, the risk of getting tainted files is still there when you need to update your dependencies. This means you get new versions of files from the GitHub repository you source from, hoping these are still malware-free or uncorrupted.

We don’t just report on threats—we remove them

Cybersecurity risks should never spread beyond a headline. Keep threats off your devices by downloading Malwarebytes today.