From 71d138894ebae6ee5457794e8ef0a728da37d29c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Wed, 15 Apr 2020 13:45:34 +0200 Subject: [PATCH 1/2] Validate the Content-Type on PUT requests Return a 415 (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415) when the Content-Type does not look like a valid MIME type (in the type/subtype format) Refs #137 --- lib/remote_storage/rest_provider.rb | 5 +++++ lib/remote_storage/s3.rb | 2 ++ spec/shared_examples.rb | 10 ++++++++++ 3 files changed, 17 insertions(+) diff --git a/lib/remote_storage/rest_provider.rb b/lib/remote_storage/rest_provider.rb index 7447c53..626e55c 100644 --- a/lib/remote_storage/rest_provider.rb +++ b/lib/remote_storage/rest_provider.rb @@ -506,5 +506,10 @@ def get_directory_listing_from_redis_via_lua(user, directory) items end + def validate_content_type(content_type) + # Do not try to perform the PUT request when the Content-Type does not + # look like a MIME type + server.halt 415 unless content_type.match(/^.+\/.+/i) + end end end diff --git a/lib/remote_storage/s3.rb b/lib/remote_storage/s3.rb index c852006..ff6ac59 100644 --- a/lib/remote_storage/s3.rb +++ b/lib/remote_storage/s3.rb @@ -16,6 +16,8 @@ def format_etag(etag) end def do_put_request(url, data, content_type) + validate_content_type(content_type) + deal_with_unauthorized_requests do md5 = Digest::MD5.base64digest(data) authorization_headers = authorization_headers_for( diff --git a/spec/shared_examples.rb b/spec/shared_examples.rb index 9255f9c..30c44ae 100644 --- a/spec/shared_examples.rb +++ b/spec/shared_examples.rb @@ -232,6 +232,16 @@ def storage_class _(last_response.body).must_equal "Precondition Failed" end end + + describe "Content-Type" do + it "must be in the type/subtype format" do + header "Content-Type", "text" + + put "/phil/food/invalid_content_type", "invalid" + + _(last_response.status).must_equal 415 + end + end end end From c2d5fc9e07c3ba77d51fcf85c2edfbf40ae4a230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Wed, 15 Apr 2020 14:23:12 +0200 Subject: [PATCH 2/2] Move the Content-Type format validation with the other validations --- lib/remote_storage/rest_provider.rb | 8 +++----- lib/remote_storage/s3.rb | 2 -- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/remote_storage/rest_provider.rb b/lib/remote_storage/rest_provider.rb index 626e55c..740c053 100644 --- a/lib/remote_storage/rest_provider.rb +++ b/lib/remote_storage/rest_provider.rb @@ -118,6 +118,9 @@ def get_directory_listing(user, directory) end def put_data(user, directory, key, data, content_type) + # Do not try to perform the PUT request when the Content-Type does not + # look like a MIME type + server.halt 415 unless content_type.match(/^.+\/.+/i) server.halt 400 if server.env["HTTP_CONTENT_RANGE"] server.halt 409, "Conflict" if has_name_collision?(user, directory, key) @@ -506,10 +509,5 @@ def get_directory_listing_from_redis_via_lua(user, directory) items end - def validate_content_type(content_type) - # Do not try to perform the PUT request when the Content-Type does not - # look like a MIME type - server.halt 415 unless content_type.match(/^.+\/.+/i) - end end end diff --git a/lib/remote_storage/s3.rb b/lib/remote_storage/s3.rb index ff6ac59..c852006 100644 --- a/lib/remote_storage/s3.rb +++ b/lib/remote_storage/s3.rb @@ -16,8 +16,6 @@ def format_etag(etag) end def do_put_request(url, data, content_type) - validate_content_type(content_type) - deal_with_unauthorized_requests do md5 = Digest::MD5.base64digest(data) authorization_headers = authorization_headers_for(