Arbitrary Repository Clone / File Disclosure
This was discovered during our external whitebox testing. I'm not sure they've considered all possible exploits for this vulnerability. They might be able to duplicate the previous disclosure of any file on the system by symlinking the right
location inside .git
.
The text from the report:
Details
When importing GitLab projects from a GitLab project backup tarball the follow- ing decompression method tries to prevent symlinks within the extracted tar- balls:
def decompress_archive
result = untar_zxf(archive: @archive_file, dir: @shared.export_path)
raise Projects::ImportService::Error.new("Unable to decompress
#{@archive_file} into #{@shared.export_path}") unless result
remove_symlinks!
end
def remove_symlinks!
Dir["#{@shared.export_path}/**/*"].each do |path|
FileUtils.rm(path) if File.lstat(path).symlink?
end
true end
The above glob pattern #{@shared.export_path}/**/*, however, catches only files which do not start with a dot. If the tarball contains symbolic links which start with a dot, those will not be removed. As a result an attacker might clone arbitrary repositories on the GitLab host. In a legit GitLab backup the to be restored git repository is stored in form of a git bundle within a file called project.bundle. When a project is imported from an export tarball the GitLab server will issue a git clone command in order to restore the git repository for the project. An attacker can now provide a mali- cious tarball with the following contents in order to get access to a repository:
./project.json
./VERSION
./project.bundle/
./project.bundle/.git # symlink to target repository
The .git symlink in the project.bundle repository will not be removed as it will not be listed with the above glob pattern. Therefore the git clone process will clone the repository targeted by the symbolic link.
Another attack vector bypassing this glob pattern is e.g. placing dot-prefixed symlinks into the upload directory. As a result, arbitrary files from the GitLab server might be read with the permission of the git user.
Reproduction Steps
Unpack a regular exported GitLab project and remove the project.bundle file. Create a project.bundle directory in the same folder. Within this project.bundle directory create a symbolic link to /var/opt/gitlab/git-data/repositories/
Recommendation
The remove_symlinks method should be improved in a way that files starting with a dot (.) are checked for symbolic links as well.