Deleting branch and merge request from a repository does not hide or delete the changes made in the merge request
HackerOne report #2795371 by f3rn0s on 2024-10-21, assigned to @ottilia_westerlund:
Report | Attachments | How To Reproduce
Report
Summary
GitLab provides mechanisms for users to delete merge requests and associated branches, but currently the functionality will leave behind orphaned commits that are never automatically cleaned. An attacker can enumerate through the merge requests visible from the web UI or API, and spot missing incremental IDs. With these IDs, the attacker can then check to see if there exists a git remote that matches the deleted merge request, and then recover the changes.
Steps to reproduce
- Create a repository on GitLab
- Create a branch and push sensitive information
- Create a merge request for the branch
- Delete the branch, then delete the merge request
- Clone a fresh copy of the repository and use
git ls-remoteto find the still persisting git remote for the merge request. - Use
git fetch origin sha_hash_of_committo pull the commit of the merge request down into the local repo. - Use
git checkout sha_hash_of_committo checkout the commit. - Use
git log -p -vto observe the changes made in the commit, and observe any sensitive information remaining.
I have created a test repository here:
https://gitlab.com/f3rn0s/theres-no-such-thing-as-flags/
From the web UI you can observe there is an open merge request (identified as 2) that implies that there is some missing merge request. Using a tool I developed, I can quickly identify that there is a hidden remote that points at this now deleted merge request:
To manually re-create these steps you would use git directly:
We can observe from these screenshots that an anonymous user can retrieve the flag from the repository, even though from the maintainers perspective they have deleted both the branch the flag existed on, as well as the merge request originally created.
Impact
Users who are not aware of this functionality may erroneously believe that after deleting the merge request, and the branch the changes existing on, they have purged the repository of sensitive information. The sensitive information will then persist inside the repository and can potentially be gathered by an attacker.
What is the expected correct behavior?
Gitlab provides two modals that pop up during this process. Once when deleting the branch:
And once when deleting the merge request:
Both of these modals state that 'data loss could occur' which implies to the user that they are deleting data from the repository.
GitLab should seek to better clarify that deleting a merge request does not delete the underlying remote, or to change the functionality to remove the merge request remote when deleting the merge request.
Impact
Security impact depends on the repository affected. I first observed this behaviour on my own companys repositories, and the impact if discovered by an attacker would have been:
- (For my company) Access to a red teaming report that contained redaction fails (hence why the MR and branch were deleted to remove the report from GitLab).
- (For my company) Access to internal pricing information
An exploration of public facing repositories to expose similar issues may find similar levels of risk.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section:




