Skip to content
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

SigV4Auth should not use cached timestamps for signing requests. #149

Closed
willmcg opened this issue Oct 8, 2013 · 0 comments · Fixed by #162
Closed

SigV4Auth should not use cached timestamps for signing requests. #149

willmcg opened this issue Oct 8, 2013 · 0 comments · Fixed by #162

Comments

@willmcg
Copy link

willmcg commented Oct 8, 2013

Versions

Python Interpreter Version: 2.7.5
Botocore Version: 18.0

Issue Description:

The SigV4Auth class generates a signature timestamp in its init and uses that timestamp for signing all requests for the endpoint. This means that an endpoint can only generate correctly signed requests for 5 minutes before the requests are rejected by AWS services as having an expired timestamp.

For example:

Signature expired: 20131008T001036Z is now earlier than 20131008T001112Z (20131008T001612Z - 5 min.)

Use Case

Ran into this problem when using botocore to construct complex CloudFormation stacks that took extended periods of time to complete. I was getting signature expired errors from CloudFormation when polling for completion of the stack construction after 5 minutes because it was using the same endpoint object to poll as it used to issue the initial CreateStack.

Reproducing the Issue:

session = botocore.session.get_session()
service = session.get_service('ec2')
endpoint = service.get_endpoint('us-east-1')
<wait more than 5 minutes>
operation = svc.get_operation(<method>)
operation.call(endpoint, ...)

This will result in a 403 error with a signature expired error like this:

Signature expired: 20131008T001036Z is now earlier than 20131008T001112Z (20131008T001612Z - 5 min.)

Suggested Fix

Instead of generating a cached signature timestamp in init for SigV4Auth, it should be generated dynamically for each signature operation.

Workaround

The issue can be worked around by calling get_endpoint() for the service before each operation call which will cause a new signature timestamp to be regenerated for requests on the new endpoint and thus avoid the expired timestamp issue.

garnaat added a commit to garnaat/botocore that referenced this issue Oct 23, 2013
…oblems if you hold onto an endpoint for more than five minutes or so. The timestamp expires and the signature is rejected. We need to create a new timestamp each time add_auth is called. But we also need a way to pass in a timestamp to use for the unit tests. This fixes boto#149.
jamesls added a commit that referenced this issue Oct 31, 2013
* release-0.23.0:
  Bumping version to 0.23.0
  Update EMR model to latest version
  Make sure we include cacert.pem from requests
  Use find_packages() to build the list of packages
  Add NOTICE file for vendored requests library
  Vendor requests library at v2.0.1
  Update cloudfront xml tests with new xmlns matching API version
  Update cloudfront to the 2013-09-27 API version
  Apply operation renames before pagination configs
  Remove trailing whitespace
  Update cloudfront to 2013-09-27 API version
  Fix merge.
  Just mock datetime.datetime.now() in the test generator rather than pushing into the auth class itself.
  We are creating a timestamp in the SigV4Auth class but this causes problems if you hold onto an endpoint for more than five minutes or so.  The timestamp expires and the signature is rejected.  We need to create a new timestamp each time add_auth is called.  But we also need a way to pass in a timestamp to use for the unit tests.  This fixes #149.
  Just mock datetime.datetime.now() in the test generator rather than pushing into the auth class itself.
  We are creating a timestamp in the SigV4Auth class but this causes problems if you hold onto an endpoint for more than five minutes or so.  The timestamp expires and the signature is rejected.  We need to create a new timestamp each time add_auth is called.  But we also need a way to pass in a timestamp to use for the unit tests.  This fixes #149.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant