Merge branch 'jprovazn-upload-symlink' into 'master'
Add FileUploader.root to allowed upload paths Closes gitlab-qa#291 See merge request gitlab-org/gitlab-ce!20472
This commit is contained in:
commit
e8d7b283be
4 changed files with 36 additions and 3 deletions
5
changelogs/unreleased/jprovazn-upload-symlink.yml
Normal file
5
changelogs/unreleased/jprovazn-upload-symlink.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add /uploads subdirectory to allowed upload paths.
|
||||
merge_request:
|
||||
author:
|
||||
type: fixed
|
|
@ -84,7 +84,7 @@ module Gitlab
|
|||
def open_file(params, key)
|
||||
::UploadedFile.from_params(
|
||||
params, key,
|
||||
Gitlab.config.uploads.storage_path)
|
||||
[FileUploader.root, Gitlab.config.uploads.storage_path])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class UploadedFile
|
|||
@tempfile = File.new(path, 'rb')
|
||||
end
|
||||
|
||||
def self.from_params(params, field, upload_path)
|
||||
def self.from_params(params, field, upload_paths)
|
||||
unless params["#{field}.path"]
|
||||
raise InvalidPathError, "file is invalid" if params["#{field}.remote_id"]
|
||||
|
||||
|
@ -37,7 +37,8 @@ class UploadedFile
|
|||
|
||||
file_path = File.realpath(params["#{field}.path"])
|
||||
|
||||
unless self.allowed_path?(file_path, [upload_path, Dir.tmpdir].compact)
|
||||
paths = Array(upload_paths) << Dir.tmpdir
|
||||
unless self.allowed_path?(file_path, paths.compact)
|
||||
raise InvalidPathError, "insecure path used '#{file_path}'"
|
||||
end
|
||||
|
||||
|
|
|
@ -75,6 +75,33 @@ describe Gitlab::Middleware::Multipart do
|
|||
it_behaves_like 'multipart upload files'
|
||||
end
|
||||
|
||||
it 'allows symlinks for uploads dir' do
|
||||
Tempfile.open('two-levels') do |tempfile|
|
||||
symlinked_dir = '/some/dir/uploads'
|
||||
symlinked_path = File.join(symlinked_dir, File.basename(tempfile.path))
|
||||
env = post_env({ 'file' => symlinked_path }, { 'file.name' => original_filename, 'file.path' => symlinked_path }, Gitlab::Workhorse.secret, 'gitlab-workhorse')
|
||||
|
||||
allow(FileUploader).to receive(:root).and_return(symlinked_dir)
|
||||
allow(UploadedFile).to receive(:allowed_paths).and_return([symlinked_dir, Gitlab.config.uploads.storage_path])
|
||||
allow(File).to receive(:realpath).and_call_original
|
||||
allow(File).to receive(:realpath).with(symlinked_dir).and_return(Dir.tmpdir)
|
||||
allow(File).to receive(:realpath).with(symlinked_path).and_return(tempfile.path)
|
||||
allow(File).to receive(:exist?).and_call_original
|
||||
allow(File).to receive(:exist?).with(symlinked_dir).and_return(true)
|
||||
|
||||
# override Dir.tmpdir because this dir is in the list of allowed paths
|
||||
# and it would match FileUploader.root path (which in this test is linked
|
||||
# to /tmp too)
|
||||
allow(Dir).to receive(:tmpdir).and_return(File.join(Dir.tmpdir, 'tmpsubdir'))
|
||||
|
||||
expect(app).to receive(:call) do |env|
|
||||
expect(Rack::Request.new(env).params['file']).to be_a(::UploadedFile)
|
||||
end
|
||||
|
||||
middleware.call(env)
|
||||
end
|
||||
end
|
||||
|
||||
def post_env(rewritten_fields, params, secret, issuer)
|
||||
token = JWT.encode({ 'iss' => issuer, 'rewritten_fields' => rewritten_fields }, secret, 'HS256')
|
||||
Rack::MockRequest.env_for(
|
||||
|
|
Loading…
Reference in a new issue