gitlab-workhorse bypass when uploading nuget packages
HackerOne report #835455 by vakzz on 2020-03-31, assigned to @ankelly:
Summary
When uploading a package via the nuget api, gitlab-workhorse is signing the file param but the package param is the one that ends up being used. This allows the package.path to be specified, similar to https://about.gitlab.com/blog/2020/03/30/how-to-exploit-parser-differentials/.
Steps to reproduce
- create a project
- make a call to the api with a dummy
fileupload, and set thepackage.pathin the query params:
curl -XPUT -v -F file=@/tmp/lala.txt 'http://vakzz:$TOKEN@gitlab-vm.local/api/v4/projects/112/packages/nuget/?package.path=/tmp/ggg'
- if
/tmp/gggwas on the server it will now be accessible via the package list, eg http://gitlab-vm.local/vakzz/npm2/-/packages/56
Impact
Any file in /tmp or /var/opt/gitlab/gitlab-rails/shared/packages/tmp/uploads could potentially be read.
It's also possible to get the current PID of the process with using a path of /proc/self as it gets resolved and returned in the error:
curl -XPUT -v -F file=@/tmp/lala.txt 'http://vakzz:$TOKEN@gitlab-vm.local/api/v4/projects/112/packages/nuget/?package.path=/proc/self'
{"message":"insecure path used '/proc/32561'"}
Quite a few things use the PID for creating files (eg golangs tempfile https://golang.org/src/io/ioutil/tempfile.go?s=1419:1477#L24) meaning it could be possible to determine other packages being uploaded (with some brute forcing) .
What is the current bug behavior?
The user has full control over the package.* params and gitlab believes they came from the workhorse
What is the expected correct behavior?
The package param should be signed and used instead of the file param
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
Any file in /tmp or /var/opt/gitlab/gitlab-rails/shared/packages/tmp/uploads could potentially be read.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
