Repository navigation
fix(s3): verify Content-MD5 on PutObject - #302
Merged
ArnavBalyan merged 1 commit intoOct 24, 2026
Merged
ArnavBalyan merged 1 commit into
ArnavBalyan merged 1 commit into
Conversation
PutObject ignored the Content-MD5 header, so a body corrupted in transit was stored and acknowledged. Decode the header in the handler (400 InvalidDigest if it is not a base64 16-byte digest) and compare it to the MD5 the engine already computes while draining the body. The check runs before the version is promoted, so a mismatch returns 400 BadDigest and leaves no object behind; EC staging is swept by the existing error path. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ArnavBalyan
approved these changes
Oct 24, 2026
ArnavBalyan
left a comment
Contributor
There was a problem hiding this comment.
LGTM thanks for the changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PutObject now checks the Content-MD5 header. If the body doesn't match the digest, it returns 400 BadDigest and nothing gets stored. If the header isn't a base64 16-byte digest, it returns 400 InvalidDigest.
Motivation
put_object ignored Content-MD5, so a body corrupted in transit got stored and acked. DeleteObjects already checks the header.
Changes
s3/error.rs: addBadDigestandInvalidDigest, both mapped to 400.handlers/objects.rs: decode the optionalcontent-md5header and pass the expected digest toEngine::put.engine.rs: compare the expected digest to the MD5 we already compute while draining the body, before the version is promoted. EC staging gets cleaned up by the existing error path.UploadPart isn't covered.
Testing
put_checks_content_md5_before_commit(matching digest succeeds, mismatch fails and leaves no object).cargo fmt --checkandcargo clippy --workspace --all-targets -- -D warningsare clean.cargo test --workspaceon macOS:openlake_kv_clientfails to link its pyo3 cdylib, so I excluded it. Everything else passes exceptlock_server::tests::refresh_matches_uid_and_extends_lease. It's timing based and also fails onmainhere (3/3 runs).Related issues
Related to #155
Written with Claude Code.