From the SDK documentation (link: https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html#_createPresignedRequest) the $expires parameter should denote the time at which the URL should expire.
So if I specified 2 minutes as an expiration time, after 2 minutes the URL should be invalid. My code looks like this
<?php
$s3 = $this->cloudProvider->getClient(); // S3 client
$cmd = $s3->getCommand(
'GetObject',
[
'Bucket' => $this->getSdkBucket(), // Bucket name
'Key' => "$s3Name",
]
);
$urlReq = $s3->createPresignedRequest($cmd, $expirationTime); // $expirationTime is a Unix timestamp
And I get the url that has the correct expiry time (in my case the client wanted it to be the session expiry time, and session time is 4 hours)
X-Amz-Content-Sha256=UNSIGNED-PAYLOAD
&X-Amz-Security-Token=long_string_goes_here
&X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=another_string_goes_here
&X-Amz-Date=20200907T110127Z
&X-Amz-SignedHeaders=host
&X-Amz-Expires=14400 // This decreases depending on how long the user is logged in - max 4hrs
&X-Amz-Signature=another_string_here
The problem is that this url will be valid after 4 hours.
From what I've read in this answer about expiry time (https://stackoverflow.com/a/57792699/629127), the URL will be valid from 6 hours up to 7 days, depending on the credentials used to generate it.
And I'm using the IAM credentials (ECS provider).
So does this means that no matter what value I put in the expiry variable, I won't be able to make the link valid for that time period?
The expiration time is checked by S3 and if the browser or a proxy (if you are using CloudFront, for example) has the file cached then the request won't reach S3. If it is cached in the browser then don't worry, that means the same user can access the URL after expiration only.
You can use the browser devtools to check for this. On the network tab, find the request to the signed URL and you can see if it was returned from the cache (from memory/disk cache).
Related
Bit of an odd case where my API is sent a presigned URL to write to, and a presigned URL to download the file from.
The problem is that if they send a very large file, the presigned url we need to write to can expire before it gets to that step (some processing happens in between the read/write).
Is it possible to 'open' the connection for writing early to make sure it doesn't expire, and then start writing once the earlier process is done? Or maybe there is a better way of handling this.
The order goes:
Receive API request with a downloadUrl and an uploadUrl
Download the file
Process the file
Upload the file to the uploadUrl
TL;DR: How can I ensure the url for #4 doesn't expire before I get to it?
When generating the pre-signed URL, you have complete control over the time duration. For example, this Java code shows how to set the time when creating a GetObjectPresignRequest object:
GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder()
.signatureDuration(Duration.ofMinutes(10))
.getObjectRequest(getObjectRequest)
.build();
So you can increase the time limit in such situations.
I am attempting to generate a presigned url that only allows one visit/use of the url.
I have been trying just using an expire time but from what I have tested anything under 70 seconds always gives an expired url error.
aws s3 presign s3://bucket/object --expires-in 70
The other alternative would be a short url expire time (e.g. 5 seconds) but I cannot get anything under 70 seconds to work without an expired url error.
If anything under 70 seconds gives you an error, your clock is almost certainly wrong on the machine where you are generating the signed URL.
Expiration is calculated as --expires-in seconds in the future relative to the clock on the machine where you are running aws-cli. There's an assumption that this is a trusted environment (your credentials are there) and the clock is also trusted to have been set accurately.
(The clock on the machine where the browser is being used to access the URL doesn't matter.)
Note that the fixed expiration time associated with a given URL is shown in the error message.
I have a website. the user is authorized, enters the site URL, then sets the interval in minutes (for example, 7 minutes). Then the user leaves the site.After 7 minutes, the program, the script, the service should start, I do not know how it's called and perform certain actions with the site that the user specified and then send the result to the mail. Tell me how can I do this service?What would it work even if the user came out and closed the browser. I can not understand in what direction I should move ... I use AWS from Amazon
UPD: let's describe in more detail. There is a login field, the user enters the login / password, the data is checked in a database called users, cookies are set with the user id (idUser), then the user enters one or more sites, they are stored in a database named data_ (idUser). The interval is stored in settings_ (idUser) value in the range 1-60 min. Suppose he sets the interval of 7 minutes. Then the user closes the tab, closes the browser. A specified interval (7 minutes) starts a script that takes data from the database data_ (idUser), (there are several URL sites stored there). The script processes them and sends the results of site verification to the mail. But the problem is also that the script will be one, and how to access the bd if I do not know idUser, because I can not get them from the cookie either ... Maybe I should change the database structure altogether?
Is X-Amz-Expires a required header/parameter? Official documentation is inconsistent and uses it in some examples, while not in others.
If it is not required, what is the default expiration value of a signed request? Does it equal to the maximum possible value for X-Amz-Expires parameter, which is 604800 (seven days)?
The documentation (see above links) talks about X-Amz-Expires parameter only in context of passing signing parameters in a query string. If X-Amz-Expires parameter is required, is it only required for passing signing parametes in query string (as opposed to passing them with Authorization header)?
Update:
Introduction to AWS Security Processes paper, on page 17 says
A request must reach AWS within 15 minutes of the
time stamp in the request. Otherwise, AWS denies the request.
Now what time stamp are we talking about here? My guess is that it is X-Amz-Date. If I am correct, then another question crops up:
How do X-Amz-Date and X-Amz-Expires parameters relate to each other? To me it sounds like request expiration algorithm falls back to 15 mins from X-Amz-Date timestamp, if X-Amz-Expire is not present.
Is X-Amz-Expires a required header/parameter?
X-Amz-Expires is only used with query string authentication, not with the Authorization: header.
There is no default value with query string authentication. It is a required parameter, and the service will reject a request if X-Amz-Algorithm=AWS4-HMAC-SHA256 is present in the query string but X-Amz-Expires=... is not.
<Error>
<Code>AuthorizationQueryParametersError</Code>
...
Now what time stamp are we talking about here?
This refers to X-Amz-Date: when used with the Authorization: header. Because X-Amz-Date: is part of the input to the signing algorithm, a change in the date or time also changes the signature. An otherwise-identical request signed 1 second earlier or later has an entirely different signature. AWS essentially allows your server clock to be wrong by up to 15 minutes without breaking your ability to authenticate requests. It is not a fallback or a default. It is a fixed window.
The X-Amz-Date: of Authorization: header-based requests is compared by AWS to their system time, which is of course synched to UTC, and the request is rejected out if hand if this value is more than 15 minutes skewed from UTC when the request arrives. No other validation related to authentication occurs prior to the time check.
Validation of Query String authentication expiration involves different logic:
X-Amz-Expires must not be a value larger than 604800 or smaller than 0; otherwise the request is immediately denied without further processing, including a message similar to the one above.
X-Amz-Date must not be more than 15 minutes in the future, according to the AWS system clock. The error is Request is not yet valid.
X-Amz-Date must not be more than X-Amz-Expires number of seconds in the past, relative to the AWS system clock, and no 15 minute tolerance applies. The error is Request has expired.
If any of these conditions occur, no further validation is done on the signature, so these messages will not change depending on the validity of the signature. This is checked first.
Also, the leftmost 8 characters of your X-Amz-Date: must match the date portion of your Credential component of the Authorization: header. The date itself has zero tolerance for discrepancy against the credential (so, when signing, don't read your system time twice, else you risk generating an occasional invalid signature around midnight UTC).
Finally, requests do not expire while in the middle of processing. If you send a request using either signing method that is deemed valid when it arrives but would have expired very soon thereafter, it is always allowed to run to completion -- for example, a large S3 download or an EBS snapshot creation request will not start, then fail to continue, because the expiration timer struck while the request had already started on the AWS side. If the action was authorized when requested, then it continues and succeeds as normal.
I am using Wso2 API Manager 1.8. I have created some apis in it, and subscribed it to an application. I Want to make the token expire time to infinte , means never expire token. I have gone through the tutorial given in wso2 site and done following changes.
refered link : Changing the default token expiration time
I have changed ApplicationAccessTokenDefaultValidityPeriod to -1 . Rest remains same. And I created new application to get the changes, Now get long integer value 9223372036854452224 ie 106751991 days) as expire time. And working fine .
Then I changed the system date to next day check whether the expire not set to zero. But my token expire time chages to 3600000 milliseconds, How this happens, even if the time reduces this much change never expecting.
I have chages the default H2 database to mysql and done same thing with this.
Then I noticed that when the day changes,the token expire time reduces from 9223372036854452224 to 3600000 milliseconds means 1hr of expire time, which is default time. Actually it have 106751991 days expire time. How this happening ?
Please help. How can I solve this problem
Set token validity time to -1 (minus one) - that means never expires (also, see if that is the value that you have in API Store on Subscriptions tab)