Include Content-Length in signature for ActiveStorage direct upload

[CVE-2020-8162]
This commit is contained in:
Travis Pew 2020-05-14 11:17:46 -04:00 committed by Aaron Patterson
parent 092a9dd4bd
commit c0ab9a7d29
No known key found for this signature in database
GPG Key ID: 953170BCB4FFAFC6
2 changed files with 25 additions and 1 deletions

View File

@ -80,7 +80,8 @@ module ActiveStorage
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
instrument :url, key: key do |payload|
generated_url = object_for(key).presigned_url :put, expires_in: expires_in.to_i,
content_type: content_type, content_length: content_length, content_md5: checksum, **upload_options
content_type: content_type, content_length: content_length, content_md5: checksum
whitelist_headers: ['content-length'], **upload_options
payload[:url] = generated_url

View File

@ -55,6 +55,29 @@ if SERVICE_CONFIGURATIONS[:s3]
@service.delete key
end
test "directly uploading file larger than the provided content-length does not work" do
key = SecureRandom.base58(24)
data = "Some text that is longer than the specified content length"
checksum = Digest::MD5.base64digest(data)
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size - 1, checksum: checksum)
uri = URI.parse url
request = Net::HTTP::Put.new uri.request_uri
request.body = data
request.add_field "Content-Type", "text/plain"
request.add_field "Content-MD5", checksum
upload_result = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.request request
end
assert_equal "403", upload_result.code
assert_raises ActiveStorage::FileNotFoundError do
@service.download(key)
end
ensure
@service.delete key
end
test "upload a zero byte file" do
blob = directly_upload_file_blob filename: "empty_file.txt", content_type: nil
user = User.create! name: "DHH", avatar: blob