Unauthorized user can delete protected branch's merge access levels and push access levels
This finding by a HackerOne reporter allows any user (unauthenticated for public projects) to delete protected refs:
This is not an ~S1/~P1 because it requires a method of finding the ids.
Link: https://hackerone.com/reports/406585 Date: 2018-09-06 18:54:53 +0000
Details: A project owner can set up protected branches for a repository. A protected branch specifies the required merge access level and push access levels. In GitLab EE, these access level objects can be destroyed. However, the applications lacks any form of authorization, which allows an unauthenticated user or Guest user to delete these access level objects. This may cause a denial of service because the enabled access level cannot merge or push to the specific branch anymore.
Steps to reproduce
As the victim
- sign in as a user
- create a project
- push a commit to the repository
- create a protected branch with any push and merge access levels
As the attacker
- sign in as a user (note: optional in case the project is publicly accessible)
- send the following request to the server to delete the
merge_access_level
object:
Request
DELETE /:namespace/:project/protected_branches/4/merge_access_levels/4 HTTP/1.1
Host: gitlab-instance
...
- in the request above, substitute the ID of the protected branch and the merge access level object. These IDs are generally very close to each other and can be easily enumerated because they're auto incremental.
- when the protected branch or merge access level object isn't found, the server will respond with a 404. When the object was deleted successfully, the server will reply as following:
Response
HTTP/1.1 302 Found
...
<html><body>You are being <a href="http://gitlab-instance/:namespace/:project/protected_branches/4">redirected</a>.</body></html>
- to confirm that an object was deleted, sign back in as the victim, and navigate to the protected branches settings page. The protected branch will be rendered as following:
{F343118}
- as can be seen, the "Allowed to merge" column is reset to "Select" instead of the original value. In this case the
merge_access_level
was deleted.
This was tested against GitLab v11.2.3-ee and v11.3.0-rc4-ee.
Impact
The victim may not be able to push to the repository or merge a merge request.
Timeline: 2018-09-06 18:57:38 +0000: @jobert (comment) The following three endpoints are vulnerable to the issue described above:
-
Projects::ProtectedTags::CreateAccessLevelsController#destroy
(ee/app/controllers/projects/protected_tags/create_access_levels_controller.rb
) -
Projects::ProtectedBranches::MergeAccessLevelsController#destroy
(ee/app/controllers/projects/protected_branches/merge_access_levels_controller.rb
) -
Projects::ProtectedBranches::PushAccessLevelsController#destroy
(ee/app/controllers/projects/protected_branches/push_access_levels_controller.rb
)