Comments (17)
The feature of selecting minimum expiration time is very much intended. Otherwise, there are cases where a pre-signed url with expiration of 900 seconds may not work if the credentials expire any time sooner.
from aws-sdk-ruby.
Thanks for opening up an issue. The change was in aws-sigv4:
1.6.0 (2023-06-28)
------------------
* Feature - Select the minimum expiration time for presigned urls between the expiration time option and the credential expiration time.
Selecting the minimum credentials time should have been safe.
We use these presigned URLs for authn, and the server strictly enforces the value of this parameter for safety.
Can you be specific about what server is enforcing this? Do you have a reproduction case?
from aws-sdk-ruby.
It's a server that works very much like Kubernetes does, where we leverage the presigned URL to prove the client's identity.
from aws-sdk-ruby.
Who owns the software where that validation occurs? I tested that a GetCallerIdentity presigned url will work for an expiration < 900, so any other validation that is occurring is happening elsewhere and not on any AWS service. You can verify the client's identity but perhaps not specifically look at an expiration of 900 seconds, that seems very fragile.
from aws-sdk-ruby.
@mullermp No other AWS SDK works that way. And for anything other than S3, an expiration time other than 900 doesn't actually work in general, in that AWS ignores it and uses 900 anyway. Attempting to use that field to convey when the underlying role creds expire is kind of a hack that is not supported by SigV4 spec.
from aws-sdk-ruby.
Internally the SDK teams talked about using the minimum of credential expiration and expiration time config - we need to do this for an upcoming feature. Do you have any supporting documentation for AWS ignoring the value and using 900 anyway? As I said in the previous message - expiration in the URL was not always a guarantee if the credentials were expiring before 900 seconds (or whatever was configured for the URL)
from aws-sdk-ruby.
@mullermp It is mentioned in the Go SDK, and confirmed by our own experimentation. https://pkg.go.dev/github.com/aws/aws-sdk-go/aws/request#Request.Presign
The expire parameter is only used for presigned Amazon S3 API requests. All other AWS services will use a fixed expiration time of 15 minutes.
As has always been the case for presigning, if the role creds expire first, then the presigned URL is no longer valid. However, if, say, your role creds are valid for one hour, and you presign STS GetCallerIdentity with X-Amz-Expires=600, it is still is valid for 15 minutes. Hence, attempting to use X-Amz-Expires to hold the role cred expiration is kind of a hack, and in general no one can rely on a value other than 900 to mean anything.
from aws-sdk-ruby.
I think STS is an exceptional case where the credentials, even when expired, will still work when calling GetCallerIdentity. Other presigned URLs like for RDS and Polly will not work this way.
from aws-sdk-ruby.
I'll ask around internally.
from aws-sdk-ruby.
@mullermp The other thing I want to point out is I don't think this new behavior of "clamping" the presigned expiration is the right solution, even for S3. Let's say my role creds expire in 10 minutes and I try to generate a presigned S3 url for 30 minutes. As per this change, you will instead generate a presigned url with X-Amz-Expires set to 10 minutes. But that doesn't really help as the presigned URL was only valid for 10 minutes anyway. I think the better thing to do in that situation is to just refresh the credentials first, so the resulting presigned url is valid for the intended duration.
from aws-sdk-ruby.
When vending presigned urls to another party (a very common case of presigned urls), the recipient doesn't know anything about what credentials were used and when they may expire. Previously the vended url would indicate 30 minutes expiration in your example and the third party would be surprised when it doesn't work. Both the vendor and the recipient will know exactly when the URL will no longer be valid.
from aws-sdk-ruby.
@mullermp Only if they know the presigned url came from this SDK, using role credentials whose expiration is known to you. And as I mentioned, I believe the desired behavior would be to refresh the credentials to honor the requested expiration, not to clamp it.
from aws-sdk-ruby.
Refreshing does not guarantee that credentials will be valid for longer than 900 seconds, the previous default. Some credential types only last 5 minutes.
from aws-sdk-ruby.
Sure, but that's less common, and would consistently not work as expected. This change still does not address the original problem, which is that I want a presigned URL valid for a certain duration, but sometimes the SDK fails to do so. Hence the SDK should first check if credential expiration < presigned expiration. If so, force a refresh. Only after that would clamping be reasonable.
from aws-sdk-ruby.
Some clarification I got from STS is that, GetCallerIdentity will always succeed if the access key id is still known (hasn't been fully rotated) - this means that the expiration parameter is not considered.
I talked with some other engineers on other SDKs. This is another potential approach we can take -
introduce a presigner option that has three modes:
-
ignore_expiration (default) - This is the previous behavior (I would have to partially revert the change) where the URL always had the expiration that was configured by the presigner, ignoring credential expiration.
-
refresh_if_will_expire - This would refresh the credentials before generating a presigned url. It would potentially have the same issue where credentials may expire before the URL indicates that it may expire.
-
require_full_signing_duration - This would refresh the credentials before generating a presigned url AND compare expiration to the configured amount. If the credentials expire before the configured amount, raise an error.
from aws-sdk-ruby.
@rittneje Did you have any preference on the above?
from aws-sdk-ruby.
require_full_signing_duration
might be a little dicey if you are off by a few seconds. For example, if my role assumption is valid for one hour, and I try to generated a presigned URL valid for one hour. Maybe it should add some buffer to the role expiration before taking the minimum. Also raising an error sounds like a harsh penalty. Perhaps the SDK should just log a warning under refresh_if_will_expire
instead?
from aws-sdk-ruby.
Related Issues (20)
- Add a way to disable checksum_mode HOT 1
- SDK fails to use SSO credentials configured via `aws configure sso` HOT 2
- aws-sdk-translate - translate_document returns text in wrong encoding HOT 6
- Stub response_target HOT 7
- Object#download_file Add Progress Callback HOT 3
- SDK throw ArgumentError when the "workgroup_name" input is valid in Aws::RedshiftDataAPIService::Client HOT 3
- [SES] Custom verification email template no redirect HOT 9
- SQS QueuePoller sometimes returns dupe messages, raises BatchEntryIdsNotDistinct HOT 1
- DynamoDB #query method returns response with items = nil HOT 18
- Aws::S3::PresignedPost does not support tagging field HOT 3
- Multipart copy for Glacier
- CognitoIdentityCredentials is not including the logins set when getting credentials, making all requests unauthenticated HOT 5
- `Aws::BedrockRuntime::Types::<X>` doesn't have `event_type=` HOT 3
- Listing shared RDS Clusters raises an ArgumentError HOT 6
- Errors downloading files from s3 are propagated to incorrect thread HOT 8
- aws-sdk-sqs raises NoMethodError when messages not found HOT 14
- Generate RBS HOT 15
- aws-partitions 1.856.0 no longer be found in that source HOT 8
- aws-sigv4/eventstream released a minor version bump after removing support for Ruby 2.3/2.4 HOT 5
- [aws-sdk-sqs] Aws::SQS::Types::SendMessageBatchResult#failed returns nil HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aws-sdk-ruby.