New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix presign urls that are not for S3 #767
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for writing this. I have a few requests, in addition to the inline comments:
- Please add an entry to
/lib/amazonka/CHANGELOG.md
. - Please add a haddock to the
Chunked
constructor ofRequestBody
pointing toChunkedBody
, something like-- | Currently S3 only, see 'ChunkedBody' for details
. - Please confirm that this change fixes the generation of presigned URLs for your RDS use case and does not break them for S3 (at least a
PutObject
and aGetObject
on a private bucket should suffice).
(Please force-push your changes) |
@endgame I have addressed all your comments. Please let me know if you want me to do further changes. The only thing left to do is the testing of S3 requests that you suggested (I will look into that tomorrow). One more question. These fixes are based on Amazonka 2.0. What about patching 1.6? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more nit, but I am otherwise happy with how this looks. Because it touches something so critical, I want @brendanhay to have a chance to look over it too. Because it's a long weekend in most of the world, I think I will merge in 14 days unless Brendan approves it sooner.
Thanks for agreeing to do the S3 tests; let me know how they go.
One more question. These fixes are based on Amazonka 2.0. What about patching 1.6? |
Don't worry about it. 1.6 has been stale for so long that the folklore has been "use latest git" for years, and 2.0 RC1 came out late last year. 2.0 has had so many new services, correctness fixes and ergonomics fixes that I recommend you use it regardless. |
@endgame I have tested |
Yeah, the pre-signing capability I'd love to see tested is a pre-signed Such uploads seem like a pretty central test case for presigned URLs with unsigned payloads, and if that works then I'm happy. |
ff5dc56
to
a1aa281
Compare
@endgame Alright, I am failing to do the
and then I generate the presigned URL with:
This gives me back a presigned URL. I noticed that I am hitting the
But when I tried uploading the file with cURL: AWS responds with:
|
I don't think that's right - I think you're hitting the For a presigned However, I am concerned that we're getting a signature mismatch in the |
I just ran this test and it was successful. It generated a URL that I then used through Insonmia to send a PUT request without a body. Then I confirmed on S3 and I saw a txt file created with 0kb. |
@endgame After running the same test I saw that the last part of the response that I get from AWS is:
There you see
Moreover, looking at the presign documentation from the AWS cli, you never speficified a file there, which leads me to think that the body to presign the URL is always |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for doing all this digging. I found a couple more things while spelunking the code this morning. Also, can you please clarify a couple more things for me:
- Your test with the unsigned
PUT
which created a zero-byte file - can you confirm that it works if you actually upload some data? - Your most recent comment sometimes writes
UNSIGNED PAYLOAD
(with space) and sometimesUNSIGNED-PAYLOAD
(with hyphen). Did you meantUNSIGNED-PAYLOAD
(with hyphen) everywhere? I cannot findUNSIGNED PAYLOAD
(with space) anywhere inbotocore
. I agree that we want to check for S3 in theHashedStream
case and returnUNSIGNED-PAYLOAD
there. If you push that change, I will review again. - I am still worried that presigning with a known payload may still be busted. Can we test that by presigning a request for (it's silly but free)
dynamodb:CreateTable
?
Actually, I am not convinced of this - we've gone to all the work of streaming this file and hashing it. We know the payload and it should match! I am now suspicious that something is actually wrong with how we calculate this, and that's why it's not working. Unless S3 has some weirdness where it's known to reject presigned |
Yeah, I am able to upload the file even if I create an unsigned PUT for a zero-byte file (just because that hits the case
Apologies for the confusion, I meant UNSIGNED-PAYLOAD (with hyphen). Given your last comment where you explain that you still have doubts about ignoring the hashed stream and using UNSIGNED-PAYLOAD, I will wait on this.
I will try to do this test today and get back to you. |
- If the body is HashedBody and == "", and the service is s3: hash "UNSIGNED-PAYLOAD" - If the body is HashedBody but either of the above conditions fail: hash the body as provided to presign. - If the body is ChunkedBody, hash "UNSIGNED-PAYLOAD". This is an edge-case I'd hardly expect to see: we don't want to consume the stream to hash it, and I can't imagine a sensible architecture that wants to presign requests (implying that the presigned request is handed off to something else) but has the stream on hand (what "somewhere else" is going to have the same stream we do?).
Yeah, I believe that's one of the major purposes of this feature: allow the caller to upload something to a fixed location. Did your have any luck presigning with a known payload? |
Unfortunately not. I am able to generate the presigned URL by doing
But no idea how to actually use the URL to send the request with curl. Where can I see the JSON payload before it gets hashed in Amazonka? Maybe I can copy that string and send it as a body? |
The body will be assembled using amazonka/lib/services/amazonka-dynamodb/gen/Amazonka/DynamoDB/CreateTable.hs Lines 686 to 709 in b7d98d3
This is because its
Which is defined in amazonka/lib/amazonka-core/src/Amazonka/Request.hs Lines 76 to 77 in b7d98d3
The easiest thing to do is probably to call |
So doing encode on the
Which I use to curl the URL returned in the presign:
And now I am getting I get the same result even if I send an empty payload or if I do |
I won't have time to read this weekend, but on Tuesday I intend to read the AWS Sigv4 stuff closely and will try and figure out what we're doing wrong. I'm starting to think we're in "did this ever work outside S3?" territory. Your RDS token stuff is working though, right? |
Yes. It works as intended. |
I've spent this week looking at the generator instead. I should be able to look at this in the next day or so. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'm fairly certain that we've made things better, and haven't made anything worse by mistake. Thank you.
Fixes #766