S3 Object Integrity Algorithms and Presigned URLs
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 35/100
調査の方向性
gems/aws-sdk-s3/lib/aws-sdk-s3/presigner.rb から始め、特に issue で参照されている checksum-handler の削除と header-hoisting の動作を確認してください。checksum_algorithm が指定された場合に生成される署名付きヘッダーを、Content-MD5 の動作と比較してください。指定された checksum ヘッダーが署名され、異なる checksum を使った upload が同じ URL では成功できなければ完了です。
索引モデルが issue の本文から書いたものです。
説明
Describe the bug
Hey there - thanks for making a great library!
I'm trying to use the SDK to generate a presigned S3 PUT URL that enforces object integrity as documented using the SHA256 checksum algorithm.
After looking through the source, it appears that the Aws::S3::Presigner does not support generating presigned URLs that specify the x-amz-checksum-{algorithm} header as a signed header value.
At first glance this feels like a defect, therefore submitting as a bug. Happy to treat this as a feature request though - thanks!
Regression Issue
- Select this option if this issue appears to be a regression.
Expected Behavior
Calling Aws::S3::Presigner#presigned_url with a checksum_algorithm value generates a URL that specifies the necessary checksum headers as signed headers.
Current Behavior
Calling Aws::S3::Presigner#presigned_url with a checksum_algorithm value generates a URL with the checksum headers as unsigned headers - meaning that the recipient of the URL can't utilize object integrity checks.
Reproduction Steps
Here's a minimal script that demonstrates the issue:
require 'bundler/inline'
require 'net/http'
gemfile do
source 'https://rubygems.org/'
gem 'aws-sdk-s3', '~> 1.182.0'
gem 'marcel', '~> 1.0.4'
gem 'nokogiri', '~> 1.18.5'
gem 'rest-client', '~> 2.1.0'
end
class FileAttributes
attr_reader :bytesize, :checksum, :mime_type
def initialize(path)
@bytesize = File.read(path).bytesize
@checksum = digest(path)
@mime_type = Marcel::MimeType.for(Pathname.new(path))
end
private
def digest(path)
Digest::SHA2.new.tap do |sha|
File.open(path) do |f|
while chunk = f.read(256)
sha << chunk
end
end
end.base64digest
end
end
def upload_file(path, attributes, url, headers: {})
puts "==> Uploading #{path}..."
puts "Request: PUT #{url}"
response = RestClient::Request.execute(
url: url,
method: :put,
headers: { 'Content-Type' => attributes.mime_type }.merge(headers),
payload: File.new(path)
)
puts "Response: #{response.code}"
rescue RestClient::ExceptionWithResponse => e
puts "Error: #{e.response.body}"
end
attributes = FileAttributes.new('file_one.png')
presigner = Aws::S3::Presigner.new
presigned_url = presigner.presigned_url(
:put_object,
bucket: ENV.fetch('BUCKET_NAME'),
key: 'test',
checksum_algorithm: 'SHA256',
checksum_sha256: attributes.checksum,
expires_in: 3600,
content_type: attributes.mime_type,
content_length: attributes.bytesize
)
# Request succeeds as expected
upload_file('file_one.png', attributes, presigned_url)
# Uploading with a _different_ checksum using the same URL succeeds, but SHOULD fail
upload_file('file_two.jpeg', attributes, presigned_url)
# Specifying x-amz-checksum-sha256 fails with 403 (HeadersNotSigned)
upload_file(
'file_one.png',
attributes,
presigned_url,
headers: { 'x-amz-checksum-sha256' => attributes.checksum }
)
Save the script as script.rb and provide two different test files in the same directory (file_one.png and file_two.jpeg).
Execute the script as follows:
BUCKET_NAME=bucket ruby script.rb
Possible Solution
Avoid removing the checksum handler and don't hoist the checksum headers when the presigned URL is being generated.
Additional Information/Context
It's worthwhile to note that the Content-MD5 header is treated as a signed header for presigned URLs. This is different than the behaviour when a different algorithm is specified.
Gem name ('aws-sdk', 'aws-sdk-resources' or service gems like 'aws-sdk-s3') and its version
aws-sdk-s3, 1.182.0
Environment details (Version of Ruby, OS environment)
Ruby 3.3.6, MacOS 15.3.2
- 主要言語
- Ruby
- スター
- 3.7k
- フォーク
- 1.2k
- 平均マージ
- 1日 15時間
- マージ済み PR(30日)
- 24
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
aws/aws-sdk-ruby のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
aws/aws-sdk-ruby#3460 ·
メンテナーはふだん 1 日以内に返信
-
service-api
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
aws/aws-sdk-ruby#3395 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
BedrockAgentCore: invoke_agent_runtime buffers entire response instead of streaming in real-timeオープンdocumentation p3 queued
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
aws/aws-sdk-ruby#3348 · コメント 6 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
feature-request needs-major-version
難易度 3/5 1〜2日 初心者へのやさしさ 48/100
aws/aws-sdk-ruby#3241 · コメント 5 件 ·
メンテナーはふだん 1 日以内に返信
-
service-api
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
aws/aws-sdk-ruby#3191 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
aws/aws-sdk-ruby の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
glossarist/glossarist-ruby#247 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
voxpupuli/puppet-corosync#589 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
🐛 bug 🧑💼 conseillers
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
betagouv/conseillers-entreprises#4768 ·
メンテナーはふだん 1 日以内に返信
-
`github-events` aborts the repository scan when a closed pull's API payload has a null `head`対応中かも @renyamamoto2026-cmyk が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
zerocracy/judges-action#2823 ·
メンテナーはふだん 1 日以内に返信