Lack of filtering in GIT_FETCH_EXTRA_FLAGS CI option allows Developer to run a protected pipeline from that can disclose protected CI/CD variable
HackerOne report #2033561 by samuellg
on 2023-06-21, assigned to @ottilia_westerlund:
Report | Attachments | How To Reproduce
Report
Summary
Any user allowed to run pipelines on a branch (even a protected one) can run it with arbitrary code from another branch/commit.
Steps to reproduce
- The attacker must have at least a
developer
role on the project and he must be allowed to run pipelines on protected branches (i.e. he must be able to accept Merge Requests). - The attacker creates a branch on the project. Let's call this branch
somebranch
. He commits arbitrary code, that will later be executed within the context of a protected branch pipeline. - If the target branch is
main
, the attackers note down the commit ID of themain
branch HEAD reference. For example:c709254daa03cda29815acf7117ed8842aecda70
. - The attacker runs a pipeline on the
main
branch, and add the following CI variables from the "Run pipeline" form:
GIT_FETCH_EXTRA_FLAGS
:c709254daa03cda29815acf7117ed8842aecda70 --force --refmap='' somebranch:refs/heads/c709254daa03cda29815acf7117ed8842aecda70
- All the jobs executed in the pipelines will be executed with the code from
somebranch
instead of the code frommain
. In the example provided in the attached project, the filesomefile
is read fromsomebranch
instead of frommain
.
Impact
Arbitrary code can be pushed to production environment. This is not visible on the attacked branch. This can also allow an attacker to steal production credentials stored within the protected CI variables.
Examples
Example here (this project has also been exported and attached to this report):
https://gitlab.com/slegoff/refmap
The branch and commit IDs are the one used in the "Steps to reproduce section".
What is the current bug behavior?
Anyone that is able to run a pipeline can choose the commit that will be checked out when running the job. The pipeline will still run within the context of the original branch (e.g. if the branch is protected, the protected variables will be available).
What is the expected correct behavior?
https://drive.google.com/file/d/10gpKnRDItwWi9Ajn2NTQq-Mq7mSfQ_ZF/view?usp=drive_link
When running a pipeline on a branch, we expect that jobs run with the code from that same branch, no matter which options are provided by the user.
Relevant logs and/or screenshots
See the attached files.
Output of checks
This bug happens on GitLab.com
Impact
The attacker can have all the pipelines job run on arbitrary code. The jobs cannot be edited through the editing of the .gitlab-ci.yml
file though, because as far as I know this file is not parsed by the runner.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
- 2023-06-21_15-30-729_slegoff_refmap_export.tar.gz
- Capture_d_e_cran_2023-06-21_a__17.39.56.png
- Capture_d_e_cran_2023-06-21_a__17.41.27.png
- Capture_d_e_cran_2023-06-21_a__17.43.34.png
How To Reproduce
Please add reproducibility information to this section:
Proposal(s)
Option 1
- Ensure that the runner git checkout command always checks out by SHA, instead of inferring the branch name