Skip to content

An attacker can run pipeline jobs as arbitrary user

Please read the process on how to fix security issues before starting to work on the issue. Vulnerabilities must be fixed in a security mirror.

HackerOne report #2057633 by vaib25vicky on 2023-07-08, assigned to GitLab Team:

Report | 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
  2. Add victim as Owner
  3. 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
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`
  1. Start an Ultimate trial for your group

  2. 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.
    • 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
  3. 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

---  
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.**
  1. After above steps, a new project is created in your group with name like test-security-policy-project
  2. Go to your test-security-policy-project Protected branch settings and choose Allow to push Maintainers and Developers
  3. Clone that test-security-policy-project to your local computer
  4. Change your git config and include username of the your victim that is,
    git config --global user.name "victim"
  5. Edit policy.yml file in your test-security-policy-project and just change description. No need of anything else.
  6. git push origin main to merge your changes in test-security-policy-project .
  7. In the policy.yml file commit history you'll see that your victim is the last edited user here.
  8. 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:

Edited by Nick Malcolm