Pipeline script injection by adding arbitrary command in post checkout hook & changing hook path to run command in future pipeline on target runner
HackerOne report #2525777 by xorz
on 2024-05-30, assigned to GitLab Team
:
Report | Attachments | How To Reproduce
Report
Summary
An attacker who has permissions to push code can inject code for any pipelines within a project with docker executor runner.
Steps to reproduce
-
sign in as user_a
-
create a new project
project_a
-
register and keep only one runner (docker) for the project. https://docs.gitlab.com/runner/executors/docker.html
-
invite the
user_b
as a developer -
goto
project_a > Build -> Pipeline Editor
-
the
user_a
should see the pipeline is green -
sign in as
user_b
-
goto the project
project_a > Code >Repository
-
create a branch
test
-
wait for the pipeline is done
-
sign in as
user_a
-
goto the project
project_a > Build > Pipelines
-
trigger a new pipeline on branch
main
-
wait for the pipeline is done
-
then the
user_a
should see the text likeCI_JOB_TOKEN
outputted by the inject code in job logs
Impact
- Get all the environment variables and access other projects. As it says on Gitlab Docs
You can use a job token to authenticate with GitLab to access another group or project’s resources (the target project). By default, the job token’s group or project must be added to the target project’s allowlist.
- Inject code to release without touch the protected branches if the project using pipeline to build and release code.
Examples
without user interaction
- two cases listed in Impact above
with user interaction
- the injected code can be run on any user's laptop after running the app downloaded from the injected releases.
- the attacker can down all the projects via stealing the ssh key if the group owner runs the released app on local.
What is the current bug behavior?
According to Choose the default Git strategy, pipelines re-use the local working copy and the customized git hooks path won't be purged for the sequential jobs.
What is the expected correct behavior?
Get the hooks path by git config core.hooksPath
.
Relevant logs and/or screenshots
Output of checks
(If you are reporting a bug on GitLab.com, write: This bug happens on GitLab.com)
Results of GitLab environment info
Gitlab
System information
System: Ubuntu 22.04
Proxy: no
Current User: user
Using RVM: no
Ruby Version: 3.2.3
Gem Version: 3.5.10
Bundler Version:2.5.10
Rake Version: 13.0.6
Redis Version: 7.0.14
Sidekiq Version:7.1.6
Go Version: go1.22.3 linux/amd64
GitLab information
Version: 17.1.0-pre
Revision: 7a6a65965a1
Directory: /home/user/dev/gitlab-development-kit/gitlab
DB Adapter: PostgreSQL
DB Version: 14.9
URL: http://gitlab.test:3001
HTTP Clone URL: http://gitlab.test:3001/some-group/some-project.git
SSH Clone URL: ssh://git@gitlab.test:2222/some-group/some-project.git
Elasticsearch: no
Geo: no
Using LDAP: no
Using Omniauth: yes
Omniauth Providers: google_oauth2
GitLab Shell
Version: 14.35.0
Repository storages:
- default: unix:/home/user/dev/gitlab-development-kit/praefect.socket
GitLab Shell path: /home/user/dev/gitlab-development-kit/gitlab-shell
Gitaly
- default Address: unix:/home/user/dev/gitlab-development-kit/praefect.socket
- default Version: 17.0.0-rc2-230-g23975a577
- default Git Version: 2.45.1
Gitlab Runner
gitlab-runner --version
Version: 17.0.0
Git revision: 44feccdf
Git branch: 17-0-stable
GO version: go1.21.9
Built: 2024-05-16T13:46:14+0000
OS/Arch: linux/amd64
Impact
-
Get all the environment variables and access other projects. As it says on Gitlab Docs
You can use a job token to authenticate with GitLab to access another group or project’s resources (the target project). By default, the job token’s group or project must be added to the target project’s allowlist.
-
Inject code to release without touch the protected branches if the project using pipeline to build and release code.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section:
Proposed fix
-
Option 1 - Add additional documentation describing using the FF_ENABLE_JOB_CLEANUP
flag to prevent this scenario. -
Option 2 - implement the recreate git template directory on each run merge request