A few weeks ago, we introduced a new class of vulnerability (Cross Fork Object Reference) and shared how they could be used to access deleted and private repo data on GitHub. Well, we’re back. Same topic, different provider. Except in some ways, it’s worse in the case of Azure DevOps (ADO).
Accessing Private Repo Data
Unlike GitHub, Azure DevOps allows private forks of public repositories. (Technically, it’s a fork of a repo from a public project into a private project.). It’s worth noting there is no formal definition of the word “Fork” because it’s not a part of the Git specification.
We discovered that when users create a private fork of a public repository and then commit data to the private fork, all of their private commits are publicly visible!
Think about it. You fork a public repo into a private project for your own internal use, but all of your private commits are public.
Let’s look at an example. If you prefer a video, click play below. If not, see the text/screenshots just below that.
Step 1: Create Two Projects: one private and one public.
Azure DevOps organizes work first by organization and then by project. Within a project, you can have multiple repositories.
Instead of housing the original repo and fork inside the same project, Azure recommends users create separate projects for forks. We’ll create one public project, which will house the “original” repo, and one private project, which will house the fork.
Step 2: Create a public repo and then fork it into the private project.
Step 3: Commit data to the private fork.
Add a commit to the private fork. Copy the SHA-1 commit hash associated with your fork. This is our “object reference” value for the Cross Fork Object Reference vulnerability.
Step 4: View the private fork commit on the public repository.
Open an incognito browser and ensure you’re not logged into Azure. Visit the public repository. Click on a commit and then swap the commit SHA-1 hash with the SHA-1 hash from your private commit in Step 3. You’ll be able to see the private commit data.
This fundamentally breaks the private/public security boundary users assume exists on Azure DevOps.
Azure Repos & Forks and their documentation
In their documentation, Microsoft specifically describes the intended functionality of forks: “A new fork…is independent of the original repo, and … any changes you make to your fork, such as adding commits or branches, aren’t shared with the original repo”.
That language implies that the Cross Fork Object Reference vulnerabilities we discovered in GitHub do not apply to ADO. Unfortunately, their documentation is inaccurate.
So, is this worse than GitHub?
Yes and no. The violation of private/public security boundaries, especially in the face of their incorrect documentation, is technically worse. However, the average developer isn’t using Azure Repos to collaborate on open-source projects. They’re using GitHub. So given the differences in user adoption rates, this doesn’t appear to impact nearly as many users.
Disclosure
We disclosed these issues to Microsoft’s Security Response Center and received this response.
MSRC responded that “The ‘fork’ process is to create a ‘copy’ of the repository using the same storage area.” That response contradicts the language used in their official documentation.
Microsoft’s documentation says “A new fork is basically a clone of the original repo pushed to a new remote repo…As an independent copy, any changes you make to your fork, such as adding commits or branches, aren’t shared with the original repo.”
The documentation leads users to believe that forks are independent and isolated from the original repo. However, MSRC explains that it’s actually sharing the same storage area.
MSRC goes on to say “This means that the visibility of the fork is the same as the initial repository”. Well, that’s not fully true. If you fork a public repo into a private project, the visibility of the fork is private. The issue is specific commits can be viewed publicly if you know the correct object reference (commit hash).
The bottom line is Microsoft’s documentation is incorrect and MSRC does not believe that accessing private repo data rises to the threshold of an “Important” security consideration.
Disclosure Note: We informed MSRC that we were publishing this post and provided them access to a draft version for a full month before publishing. They did not add any comments.
What can you do?
If you use Azure Repos, we recommend steering clear of public projects. If you must use a public project, turn off the ability to fork any of the repositories. This should largely protect you from CFOR vulnerabilities.
If there are already forks of public repositories, we recommend reviewing as much of the commit data from the forks as possible to determine how much could be exposed via the public repo.