Make it possible to prevent non-maintainer users from defining CI variables
Release notes
Problem to solve
It's impossible to have a project where the Developers have no possibility to execute arbitrary code on the runner and some users would like to create such an environment.
Summary
We introduced in 12.6 the possibility to host the .gitlab-ci.yml
file in an external project. Using this new feature, one can create a project and expect the users with Developer access and below to have no control whatsoever over the code executed on the runner. However there are a few ways to bypass that expectation.
On GitLab.com it's possible to overwrite the CI_PRE_CLONE_SCRIPT
variable and have code executed on the shared runners.
git commit --allow-empty -m "empty commit"
git push -o ci.variable="CI_PRE_CLONE_SCRIPT=id"
The pipeline output contains:
$ eval "$CI_PRE_CLONE_SCRIPT"
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
On any GitLab installation it's possible to overwrite the PATH
variable and influence the execution of the pipeline.
cat >git <<EOF
#!/bin/sh
echo evil!
id
EOF
chmod +x git
git add git
git commit -m "Add evil git script"
git push -o ci.variable="PATH=.:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Because GitLab CI runs git clean
and git lfs
inside the repository, it is possible to place a malicious git
executable inside the repository and configure PATH
to cause it to be run.
The PATH
example will work for any project, but if the malicious user is aware of any specific variable used in the CI configuration, they could override those as well if they are not protected variables.
Intended users
User experience goal
The maintainer should have the ability to completely lock down access to the code that's executing on the runner.
Proposal
A project setting should be added to the CI / CD
settings that disables user-defined variables. This includes variables set when:
- manually triggering pipelines in the UI
- manually creating pipelines via API
- manually playing a job via the UI
- using push options
- manually triggering pipelines with the API
- passing variables to a downstream pipeline
When this setting is enabled and combined with hosting the .gitlab-ci.yml
file in another project, the project settings (accessible to maintainers+ only) should be the only place where variables can be defined.
As MVC we can provide an API endpoint to enable/disable the setting.
Further details
A project setting check can be executed into Ci::CreatePipelineService
to ignore variables_attributes
if user-defined variables are disabled. We also need to change Ci::PipelineTriggerService
to pass in variables_attributes
so that the restriction is added in one place.
Permissions and Security
This setting should be available to Maintainers and Owners only.