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