Removed author of the merge request can still edit merge request’s approval rules using API
:warning: **Please read **[**the process**](https://gitlab.com/gitlab-org/release/docs/-/blob/master/general/security/engineer.md)** on how to fix security issues before starting to work on the issue. Vulnerabilities must be fixed in a security mirror.**
[**HackerOne report #2980839**](https://hackerone.com/reports/2980839) by `theluci` on 2025-02-07, assigned to `GitLab Team`:
[Report](#report) | [Attachments](#attachments) | [How To Reproduce](#how-to-reproduce)
## Report
Hello, I hope you are doing well.
I found that the author of the merge request, removed from the project can still edit merge request’s approval rules using API even when the option isn’t available when using UI.
#### Vulnerability
According to [docs](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/rules.html#edit-or-override-merge-request-approval-rules), to override the merge request’s approval rules, **You must have at least the _Developer role_ in the project.**

If the author of the merge request is removed from the project and tries to edit approval rules of the merge request, he can not do so using UI

Which is correct and as per the documentation.
**However, the check isn’t ensured when using API.**\
**That is, an author of the merge request, removed from the project can still override merge request’s approval rules using API contrary to documentation.**
#### Steps to reproduce
1. `victim` creates a public group `victim-group` and starts Ultimate trial.
2. `victim` navigates to Manage --\> Members,
+ `victim` invites `victim-member` as a _Maintainer_ to `victim-group`
+ `victim` invites `attacker` as a _Developer_ to `victim-group`
3. `victim` creates a **public project** `victim-project` inside `victim-group`.\
_(Initialize repository with a README)_
4. `victim` navigates to _Settings --\> Merge requests_, scrolls down to Merge request approvals,
+ `victim` sets the _Minimum required approvals_ to 2.
+ `victim` clicks _Add approval rule_ and selects the following configuration,


+ `victim` selects the following configuration,

**At this point, `victim` does not allow approval rules overriding and every merge request must be properly approved before being merged.**
5. `attacker` visits `victim-project`, creates a new branch `another` and makes some malicious changes.
6. `attacker` creates a merge request from `another` branch to `main`.
7. `victim` visits `victim-project`, navigates to _Code --\> Merge requests_ and selects the merge request. _(Created in step 6)_
8. `victim` sets the merge request to **auto-merge**.
`victim` hopes to merge the request after the required approval criteria has been met but not yet as to investigate/review the code further.
9. `attacker` visits `victim-project`, navigates to _Code --\> Merge requests_, selects the merge request _(Created in step 6)_ and marks it as **Draft**.
10. `victim` visits `victim-group`, navigates to Manage --\> Members and **Removes** `attacker`.
11. `victim` visits `victim-project`, navigates to _Settings --\> Merge requests_, scrolls down to Merge request approvals and **uncheck Prevent editing approval rules in merge requests**.

Now, `victim` allows approval rules overriding as only high role **trustworthy members** are in project and if required they can edit approval rules.
\<------------------------------------Important-----------------------------------------------\>
These members already have enough permissions to visit Settings and edit approval rules if required, so giving them permission to override approval rules isn’t a security concern.\
**Please note that while `attacker` was a part of the project approval rules overriding were not allowed.**
In a real-world scenario, approval rules overriding would only be allowed in a very trusting environment, where members may already have enough permission to edit approval rules from Setting if required.
Thus, for an `attacker`, not part of the project, to be able to edit a merge request’s approval rules is a grave security concern.
\<-----------------------------------------------------------------------------------------------\>
12. `attacker` visits `https://gitlab.com/api/v4/projects/<victim-project-id>/approval_settings?target_branch=main`
+ `attacker` notes the `id` of `All Members`

13. `attacker` visits `victim-project`, navigates to _Code --\> Merge requests_ and selects the merge request. _(Created in step 6)_
14. `attacker` clicks on _Edit_ and **unchecks Draft**

14. `attacker` clicks on _Save changes_ but **intercepts the request**.
15. `attacker` adds the following to the body of the request,
```
&merge_request%5Bapproval_rules_attributes%5D%5B%5D%5Bapproval_project_rule_id%5D=<ID_All_Members>&merge_request%5Bapproval_rules_attributes%5D%5B%5D%5Bapprovals_required%5D=0&merge_request%5Bapproval_rules_attributes%5D%5B%5D%5Bname%5D=&merge_request%5Bapproval_rules_attributes%5D%5B%5D%5Buser_ids%5D%5B%5D=&merge_request%5Bapproval_rules_attributes%5D%5B%5D%5Bgroup_ids%5D%5B%5D=
```
Please be sure to replace `ID_All_Members` with the ID noted in step 12.
\<redacted\>
16. `attacker` forwards the request.
`attacker` is able to **edit approval rules using API** despite not being a part of the project.
17. Merge request is merged.
#### POC
\<redactec\>
#### Output of checks
This bug happens on GitLab.com (Probably on instance too)
#### Impact
An author of the merge request, removed from the project can still override merge request’s approval rules **_using API (even though the option isn’t available when using UI)_ contrary to documentation**, which in worst-case scenario may merge malicious changes to the protected branch.
## Attachments
**Warning:** Attachments received through HackerOne, please exercise caution!
* [1feb-5.png](https://h1.sec.gitlab.net/a/fd349966-a880-4524-8d92-0eb0545ed64b/1feb-5.png)
* [1feb-6.png](https://h1.sec.gitlab.net/a/540bdf01-fd7b-4e91-83e8-a95aabe2829f/1feb-6.png)
* [6feb-1.png](https://h1.sec.gitlab.net/a/444fa10a-d7ce-4229-bf9b-cb856c0a909d/6feb-1.png)
* [6feb-2.png](https://h1.sec.gitlab.net/a/3bbca083-9758-498b-967a-a48319647b30/6feb-2.png)
* [6feb-3.png](https://h1.sec.gitlab.net/a/7f5b1b5d-ca49-44cb-ab1e-7a98a2af3a32/6feb-3.png)
* [6feb-4.png](https://h1.sec.gitlab.net/a/8a614ad6-f734-44a5-87ee-a6d1bcee1140/6feb-4.png)
* [6feb-5.png](https://h1.sec.gitlab.net/a/cf356531-389c-4fa9-a9f3-e4e12b73facb/6feb-5.png)
* [7feb-1.png](https://h1.sec.gitlab.net/a/e4b85585-5305-4a7b-8760-c5bf73b9d2ec/7feb-1.png)
* \<redacted\>
* \<redacted\>
## How To Reproduce
Please add [reproducibility information](https://about.gitlab.com/handbook/engineering/security/#reproducibility-on-security-issues) to this section:
1.
2.
3.
issue