An attacker can run pipeline jobs as arbitrary user
: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 #2057633](https://hackerone.com/reports/2057633)** by `vaib25vicky` on 2023-07-08, assigned to `GitLab Team`: [Report](#report) | [How To Reproduce](#how-to-reproduce) ## Report ##### Summary An attacker can run arbitrary pipeline jobs as a `victim user`. This means the attacker can access the user internal repositories, member only repositories, registry, etc... by using the victim `CI_JOB_TOKEN` token. It is possible by using scan execution policy which triggers the pipeline on the basis of who last commited/edited `policy.yml` file. We can include `victim` username in `git config --global user.name "victim" ` and push changes to `policy.yml` as `victim` then a new pipeline will trigger whose triggerer/author will be `victim`. All this is done, without any user interaction and only prerequisite is `victim` Gitlab username and name of `victim` internal or members-only project whose code is private. Since, there is restriction in `policy.yml` file that we can't add `scripts` or `bash commands`. However, I find a way to use `analyzer` file to run custom bash code. This allows me to exploit the bug as shown in steps. ##### Steps to reproduce on **Gitlab.com** VICTIM: * Sign in to a GitLab.com as a Victim user * Create an arbitrary public member only repository with some private files. (We will steal this repo as a poc.) ATTACKER: 1. Create a group in Gitlab.com 1. Add victim as Owner 2. Register a self-hosted runner at group level * Let it run untagged jobs * Install on an Ubuntu machine and choose executor as `shell` * SSH into your machine and create a `bash` file named `analyzer` at root level that is , `/analyzer` ```bash root@ubuntu123$ nano /analyzer ### !/bin/bash git clone https://gitlab-ci-token:${CI_JOB_TOKEN}[@]gitlab.com/<victim>/<project> ~/poc root@ubuntu123$ chmod +x /analyzer ``` * After successful exploitation, victim repository will be downloaded in ` /home/gitlab/poc` 3. Start an Ultimate trial for your group 4. Prepare the `test` project. Follow the steps below: * Create a new private project with a working `.gitlab-ci.yml` file. For example, use the [bash template.](https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/gitlab/ci/templates/Bash.gitlab-ci.yml) * Disabled shared runners for the project. Validate that the group runner created in the previous step is listed under "Available group runners: 1" * Add an empty named `package.json` to the project. This is required for the SAST scan to run. * On the left sidebar select **Code** and then **Branches** * Select **New branch** * Enter `test` as name * Select **Create branch** 5. Prepare the security policy in your `test` project * On the left sidebar, select **Secure*** and then **Policies.** * Select **New policy.** * Select **Scan execution policy** * Switch to `.yaml mode` * Replace the content with the example policy yaml below ```json --- scan_execution_policy: - name: test description: 'helloo' enabled: true rules: - type: schedule branches: - test cadence: "*/16 * * * *" actions: - scan: sast tags: [] ``` * Select **Configure with a merge request** * Select **Merge.** 6. After above steps, a new project is created in your group with name like `test-security-policy-project` 7. Go to your `test-security-policy-project` **Protected branch** settings and choose **Allow to push Maintainers and Developers** 8. Clone that `test-security-policy-project` to your local computer 9. Change your `git config` and include username of the your `victim` that is, `git config --global user.name "victim" ` 10. Edit `policy.yml` file in your `test-security-policy-project` and just change `description`. No need of anything else. 11. `git push origin main` to merge your changes in `test-security-policy-project` . 12. In the `policy.yml` file commit history you'll see that your `victim` is the last edited user here. 13. Wait for 15 mins or more, a new pipeline will run in the `test` project and you will be able to gain access to `victim` internal repository or members only repository whose code is private. ##### Output of checks This bug happens on GitLab.com. #### Impact An attacker can run pipeline jobs as arbitrary user without any user interaction allows access to internal and members-only projects whose code are private. ## 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