-
Notifications
You must be signed in to change notification settings - Fork 409
Add expiry validation for S3 gateway requests #9710
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
base: master
Are you sure you want to change the base?
Conversation
01442fe to
3915765
Compare
77a8138 to
f5fb7ba
Compare
This change adds validation for the `X-Amz-Expires` parameter in presigned URLs. Changes: - Parse `X-Amz-Expires` and validate within allowed range - Check expiration time for presigned URLs and deny request if past expiration time. - Add an explicit check for all required parameters for presigned URLs Fixes #9599
f5fb7ba to
375ec38
Compare
This change ensures that when a request doesn't have the v4 algorithm URL parameter (`x-amz-algorithm`), the chained authenticator tries the next auth method instead of failing. Previously, requests using other signature versions would fail because v4 parsing returned and error that blocked the chain.
375ec38 to
07ff93a
Compare
N-o-Z
left a comment
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.
Looks good!
Added comment inline.
In addition:
- I think it will be nice to have an esti test that checks the e2e flow with an expired presigned URL request (I think this can be done with a very short expiry) but if you think it's too much work for too less of a value let me know
- These changes fix the behavior for the V4 signer but we also have the V2 which although deprecated is still being used in some cases and is still supported in our code. We might want to consult with product regarding that. If we do need to fix this for V2 let's open a separate issue for that so this PR can converge.
| if err == nil { | ||
| c.chosen = method | ||
| return sigContext, nil | ||
| } else if !errors.Is(err, ErrHeaderMalformed) && !errors.Is(err, ErrBadAuthorizationFormat) { |
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.
Can you please add a comment here explaining why we are singling out these error types
| return expires, nil | ||
| } | ||
|
|
||
| func isV4PresignedRequest(query url.Values) error { |
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.
Nice taking this out to a separate method
| return ctx, nil | ||
| } | ||
|
|
||
| // otherwise, see if we have all the required query parameters |
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.
I think it's important to keep the comment.
I'd modify it to: "Otherwise try to parse request as presigned URL
|
|
||
| func (ctx *verificationCtx) verifyExpiration() error { | ||
| if !ctx.AuthValue.IsPresigned { | ||
| // TODO: we currently don't have handling for this |
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.
Why is that a TODO?
Is there an expiry mechanism for regular requests?
| timeDiff := now.Sub(requestTime) | ||
|
|
||
| // Check for requests from the future and allow small clock skew | ||
| if timeDiff < 0 && timeDiff.Abs() > 5*time.Minute { |
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.
Why are we checking for 5min?
What's the behavior in AWS for presigned requests that are less than 5 min in the future?
Please document
| "github.com/treeverse/lakefs/pkg/gateway/errors" | ||
| ) | ||
|
|
||
| func TestVerifyExpiration(t *testing.T) { |
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.
Nice tests - do we want to also add tests for non-presigned with expiry and check our behavior is consistent with S3?
| } | ||
| } | ||
|
|
||
| func TestParseExpires(t *testing.T) { |
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.
We should test for nil expires as well (no header)
Closes #9599
Change Description
Bug Fix
This change adds validation for the
X-Amz-Expiresparameter in presigned URLs.Changes:
X-Amz-Expiresand validate within allowed rangeTesting Details
Unit tests for the verification logic were added.
Also tested using the python test in this gist
Breaking Change?
This could be considered a breaking change if users were unaware of this issue and have been relying on presigned URLs not expiring. However, this is a security issue and should be fixed.