Commit d1d438cc authored by Yorick Peterse's avatar Yorick Peterse

Merge branch 'security-use-multipart-uploaded-file-in-maven-packages' into 'master'

Use the uploaded file set by multipart.rb in Maven packages

Closes #183

See merge request gitlab-org/security/gitlab!700
parents 5b5246fa b97cc2f7
---
title: Maven packages upload endpoint is now properly using the uploaded file set
by middleware
merge_request:
author:
type: security
...@@ -216,13 +216,7 @@ module API ...@@ -216,13 +216,7 @@ module API
params do params do
requires :path, type: String, desc: 'Package path' requires :path, type: String, desc: 'Package path'
requires :file_name, type: String, desc: 'Package file name', regexp: Gitlab::Regex.maven_file_name_regex requires :file_name, type: String, desc: 'Package file name', regexp: Gitlab::Regex.maven_file_name_regex
optional 'file.path', type: String, desc: %q(path to locally stored body (generated by Workhorse)) requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)'
optional 'file.name', type: String, desc: %q(real filename as send in Content-Disposition (generated by Workhorse))
optional 'file.type', type: String, desc: %q(real content type as send in Content-Type (generated by Workhorse))
optional 'file.size', type: Integer, desc: %q(real size of file (generated by Workhorse))
optional 'file.md5', type: String, desc: %q(md5 checksum of the file (generated by Workhorse))
optional 'file.sha1', type: String, desc: %q(sha1 checksum of the file (generated by Workhorse))
optional 'file.sha256', type: String, desc: %q(sha256 checksum of the file (generated by Workhorse))
end end
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
put ':id/packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do put ':id/packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do
...@@ -230,9 +224,6 @@ module API ...@@ -230,9 +224,6 @@ module API
file_name, format = extract_format(params[:file_name]) file_name, format = extract_format(params[:file_name])
uploaded_file = UploadedFile.from_params(params, :file, ::Packages::PackageFileUploader.workhorse_local_upload_path)
bad_request!('Missing package file!') unless uploaded_file
package = ::Packages::Maven::FindOrCreatePackageService package = ::Packages::Maven::FindOrCreatePackageService
.new(user_project, current_user, params.merge(build: current_authenticated_job)).execute .new(user_project, current_user, params.merge(build: current_authenticated_job)).execute
...@@ -244,14 +235,14 @@ module API ...@@ -244,14 +235,14 @@ module API
package_file = ::Packages::PackageFileFinder package_file = ::Packages::PackageFileFinder
.new(package, file_name).execute! .new(package, file_name).execute!
verify_package_file(package_file, uploaded_file) verify_package_file(package_file, params[:file])
when 'md5' when 'md5'
nil nil
else else
track_event('push_package') if jar_file?(format) track_event('push_package') if jar_file?(format)
file_params = { file_params = {
file: uploaded_file, file: params[:file],
size: params['file.size'], size: params['file.size'],
file_name: file_name, file_name: file_name,
file_type: params['file.type'], file_type: params['file.type'],
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe API::MavenPackages do RSpec.describe API::MavenPackages do
include WorkhorseHelpers
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project, :public, namespace: group) } let_it_be(:project, reload: true) { create(:project, :public, namespace: group) }
...@@ -484,6 +486,9 @@ RSpec.describe API::MavenPackages do ...@@ -484,6 +486,9 @@ RSpec.describe API::MavenPackages do
end end
describe 'PUT /api/v4/projects/:id/packages/maven/*path/:file_name' do describe 'PUT /api/v4/projects/:id/packages/maven/*path/:file_name' do
let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
let(:workhorse_header) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token } }
let(:send_rewritten_field) { true }
let(:file_upload) { fixture_file_upload('spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.jar') } let(:file_upload) { fixture_file_upload('spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.jar') }
before do before do
...@@ -511,14 +516,19 @@ RSpec.describe API::MavenPackages do ...@@ -511,14 +516,19 @@ RSpec.describe API::MavenPackages do
expect(response).to have_gitlab_http_status(:forbidden) expect(response).to have_gitlab_http_status(:forbidden)
end end
context 'when params from workhorse are correct' do context 'without workhorse rewritten field' do
let(:params) do let(:send_rewritten_field) { false }
{
'file.path' => file_upload.path, it 'rejects the request' do
'file.name' => file_upload.original_filename upload_file_with_token
}
expect(response).to have_gitlab_http_status(:bad_request)
end
end end
context 'when params from workhorse are correct' do
let(:params) { { file: file_upload } }
it 'rejects a malicious request' do it 'rejects a malicious request' do
put api("/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/%2e%2e%2f.ssh%2fauthorized_keys"), params: params, headers: headers_with_token put api("/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/%2e%2e%2f.ssh%2fauthorized_keys"), params: params, headers: headers_with_token
...@@ -526,6 +536,8 @@ RSpec.describe API::MavenPackages do ...@@ -526,6 +536,8 @@ RSpec.describe API::MavenPackages do
end end
context 'without workhorse header' do context 'without workhorse header' do
let(:workhorse_header) { {} }
subject { upload_file_with_token(params) } subject { upload_file_with_token(params) }
it_behaves_like 'package workhorse uploads' it_behaves_like 'package workhorse uploads'
...@@ -572,7 +584,15 @@ RSpec.describe API::MavenPackages do ...@@ -572,7 +584,15 @@ RSpec.describe API::MavenPackages do
end end
def upload_file(params = {}, request_headers = headers) def upload_file(params = {}, request_headers = headers)
put api("/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/my-app-1.0-20180724.124855-1.jar"), params: params, headers: request_headers url = "/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/my-app-1.0-20180724.124855-1.jar"
workhorse_finalize(
api(url),
method: :put,
file_key: :file,
params: params,
headers: request_headers,
send_rewritten_field: send_rewritten_field
)
end end
def upload_file_with_token(params = {}, request_headers = headers_with_token) def upload_file_with_token(params = {}, request_headers = headers_with_token)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment