14
  1. Is X-Amz-Expires a required header/parameter? Official documentation is inconsistent and uses it in some examples, while not in others.

  2. 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)?

  3. 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:

  1. 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.
golem
  • 1,820
  • 1
  • 20
  • 25
  • The *Introduction to AWS Security Processes* paper has been archived and moved to https://d1.awsstatic.com/whitepapers/Security/Intro_Security_Practices.pdf . – li ki Oct 10 '22 at 14:14

1 Answers1

19

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.

C-Otto
  • 5,615
  • 3
  • 29
  • 62
Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427
  • 1
    After researching the subject on my own (I implemented signing algorithm according to the spec) I mostly agree with you answer. However: a) X-Amz-Expires parameter is only required for S3 object uploads/downloads, it is ignored for API calls to IAM, EC2, or DynamoDB (I didn't test other services). b) UTC syncing description is a bit erroneous. UTC is a timezone, you don't sync with a timezone; request is rejected if the request creation time differs from Amazon server's time for more than 15 minutes. – golem Sep 24 '16 at 17:33
  • 1
    Regarding expiration, the technical accuracy of my answers is important to me, so I will review and test and update this answer accordingly. Regarding UTC, I wasn't referring to the UTC time zone. [*"Coordinated Universal Time, abbreviated as UTC, is the primary time standard by which the world regulates clocks and time."](https://en.m.wikipedia.org/wiki/Coordinated_Universal_Time)* Amazon server time is synchronized to *the UTC time standard,* so if your server clock is not, then you have a margin of error of less than 15 minutes. Requests fail with a server clock that is more skewed. – Michael - sqlbot Sep 24 '16 at 18:54
  • Thank you for this answer. Do you have any idea why `X-Amz-Expires` does NOT work with WebSocket URLs? It is simply not considered, and the max expiry time (5 min for WebSockets) is always used. – Mohammed Noureldin Apr 20 '21 at 09:43
  • 1
    @MohammedNoureldin it looks as if `X-Amz-Expires` is only interpreted by S3, which is a surprise to me. Other services use hard-coded limits of 15 or 5 minutes. https://stackoverflow.com/a/66961500/1695906 – Michael - sqlbot Apr 23 '21 at 11:34
  • @Michael-sqlbot I have read the same on GitHub yesterday. While this is not a major issue, this is annoying. – Mohammed Noureldin Apr 23 '21 at 13:21
  • It is also required by the AWS Transcribe Streaming API – Hari Honor Jun 15 '21 at 10:45