Arbitrary API PUT requests via HTML injection in user's name
:warning: **Please read [the process](https://gitlab.com/gitlab-org/release/docs/-/blob/master/general/security/developer.md) on how to fix security issues before starting to work on the issue. Vulnerabilities must be fixed in a security mirror.**
**[HackerOne report #2225710](https://hackerone.com/reports/2225710)** by `yvvdwf` on 2023-10-25, assigned to @kmorrison1:
[Report](#report) | [How To Reproduce](#how-to-reproduce)
## Report
Hello,
Full name of a user is sanitized by the following [function](https://gitlab.com/gitlab-org/gitlab/blob/97acd4825a295f547b804bc7fb3283a293b0254e/app/models/user.rb#L1416):
```ruby
def sanitize_name
return unless self.name
self.name = self.name.gsub(%r{</?[^>]*>}, '')
end
```
The name can be any HTML tag without closing bracket.
When it is displayed in the navigation bar of gitlab, it is sanitized once more times using [`simple_sanitize`](https://gitlab.com/gitlab-org/gitlab/blob/97acd4825a295f547b804bc7fb3283a293b0254e/app/helpers/application_helper.rb#L118) function which allows `a, span` tags and `class, href, ...` attributes.
Thus, a user's fullname can be `<a class=x href=y`
In a [merge request page](https://gitlab.com/gitlab-org/gitlab/-/blob/1407a02dbef2cd06771bc94b61724430a94890d4/app/assets/javascripts/merge_request.js#L70-94), we got this gadget:
```javascript
const draftToggles = document.querySelectorAll('.js-draft-toggle-button');
if (draftToggles.length) {
draftToggles.forEach((draftToggle) => {
draftToggle.addEventListener('click', (e) => {
...
axios
.put(draftToggle.href, null, { params: { format: 'json' } })
```
This means that if a user's fullname is `<a class=js-draft-toggle-button href=xxx` and this fullname is shown in a merge request page, then we can trick victim to execute any RESTful API PUT requests if the victim clicks on the fullname.
To easily capture victim's clicks, we can add `fixed-top` class to create a transparent topmost layer, and `tree-list-holder` class to hide this topmost layer on other pages (but the topmost shows only on a merge request page), for example, `a<a class="fixed-top tree-list-holder js-draft-toggle-button" href=xxxxxx`
### Reproduce
The vulnerability allows attackers to execute any RESTful API PUT requests on behalf of victim. The following scenario is to execute [`PUT /projects/:id/transfer`](https://docs.gitlab.com/ee/api/projects.html#transfer-a-project-to-a-new-namespace), thus to allow attacker to *steal* a victim's project by escalating to the owner of the project.
- step 0: as victim
+ create a new, private project and note its ID, e.g., `11111111` (we will steal this project: e.g., to be owner of the project)
- step 1: as attacker
+ create a new group, note its ID, e.g., `99999999`
+ invite victim as `Maintainer` of the group
- step 2: as attacker
+ create a new project, edit its readme then commit to another branch, then create a new merge request from the new branch to the default one. The objective is to have a merge request page, e.g., `https://gitlab.com/attacker/project-a/-/merge_requests/1`
+ goto attacker profile page (https://gitlab.com/-/profile), change "Full name" to: `a<a class="fixed-top tree-list-holder js-draft-toggle-button" href=/api/v4/projects/111111111/transfer?namespace=999999999` . Then click `Update profile settings` button. Important note: there must be no closed-bracket character `>` in the full name.
+ go back to the merge request page, `https://gitlab.com/attacker/project-a/-/merge_requests/1`, you should notice a topmost transparent layer.
+ change the project to public or add victim as a project member so that victim can view the merge request page
- step 3: as victim
+ visit the merge request page, then click any where
You might now notice that the project `111111111` has been transfer to the group `999999999` and attacker becomes owner of the project.
Best regards,
yvvdwf
#### Impact
The vulnerability allows attackers to execute any RESTful API PUT requests on behalf of victim.
## How To Reproduce
Please add [reproducibility information] to this section:
1.
1.
1.
[reproducibility information]: https://about.gitlab.com/handbook/engineering/security/#reproducibility-on-security-issues
issue