Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Amazon Web Services version 4 authentication for the Python Requests library.
Implements header-based authentication, GET URL parameter and POST parameter authentication are not supported.
This package has been tested as working against:
AppStream, AppSync, Auto-Scaling, CloudFormation, CloudFront, CloudHSM, CloudSearch, CloudTrail, CloudWatch Monitoring, CloudWatch Logs, CodeDeploy, Cognito Identity, Cognito Sync, Config, DataPipeline, Direct Connect, DynamoDB, Elastic Beanstalk, ElastiCache, EC2, EC2 Container Service, Elastic Load Balancing, Elastic MapReduce, ElasticSearch, Elastic Transcoder, Glacier, Identity and Access Management (IAM), Key Management Service (KMS), Kinesis, Lambda, Opsworks, Redshift, Relational Database Service (RDS), Route 53, Simple Storage Service (S3), Simple Notification Service (SNS), Simple Queue Service (SQS), Storage Gateway, Security Token Service (STS)
The following services do not support AWS auth version 4 and are not usable with this package:
Simple Email Service (SES), Simple Workflow Service (SWF), Import/Export, SimpleDB, DevPay, Mechanical Turk
The AWS Support API has not been tested as it requires a premium subscription.
In the 1.x semantic versions, the minimum python support will be gradually raised:
Install via pip:
$ pip install requests-aws4auth
requests-aws4auth requires the Requests library by Kenneth Reitz.
requests-aws4auth is tested on Python 2.7 and 3.5 and up.
Version 0.8 introduces request date checking and automatic key regeneration behaviour as default. This has implications for sharing authentication objects between threads, and for storage of secret keys. See the relevant sections below for details. See also the discussion in GitHub issue #10.
>>> import requests
>>> from requests_aws4auth import AWS4Auth
>>> endpoint = 'http://s3-eu-west-1.amazonaws.com'
>>> auth = AWS4Auth('<ACCESS ID>', '<ACCESS KEY>', 'eu-west-1', 's3')
>>> response = requests.get(endpoint, auth=auth)
>>> response.text
<?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<Owner>
<ID>bcaf1ffd86f461ca5fb16fd081034f</ID>
<DisplayName>webfile</DisplayName>
...
This example would list your buckets in the eu-west-1
region of the
Amazon S3 service.
>>> from requests_aws4auth import AWS4Auth
>>> auth = AWS4Auth('<ACCESS ID>', '<ACCESS KEY>', 'eu-west-1', 's3',
session_token='<SESSION TOKEN>')
...
This example shows how to construct an AWS4Auth object for use with STS
temporary credentials. The x-amz-security-token
header is added with
the session token. Temporary credential timeouts are not managed -- in
case the temporary credentials expire, they need to be re-generated and
the AWS4Auth object re-constructed with the new credentials.
>>> from requests_aws4auth import AWS4Auth
>>> from botocore.session import Session
>>> credentials = Session().get_credentials()
>>> auth = AWS4Auth(region='eu-west-1', service='es',
refreshable_credentials=credentials)
...
This example shows how to construct an AWS4Auth instance with automatically refreshing credentials, suitable for long-running applications using AWS IAM assume-role. The RefreshableCredentials instance is used to generate valid static credentials per-request, eliminating the need to recreate the AWS4Auth instance when temporary credentials expire.
If an HTTP request to be authenticated contains a Date
or X-Amz-Date
header, AWS will only accept the authorised request if the date in the
header matches the scope date of the signing key (see the AWS REST API date
docs.)).
From version 0.8 of requests-aws4auth, if the header date does not match
the scope date, an AWS4Auth
instance will automatically regenerate its
signing key, using the same scope parameters as the previous key except
for the date, which will be changed to match the request date. If a
request does not include a date, the current date is added to the
request in an X-Amz-Date
header, and the signing key is regenerated if
this differs from the scope date.
This means that AWS4Auth
now extracts and parses dates from the values
of X-Amz-Date
and Date
headers. Supported date formats are:
If either header is present but AWS4Auth
cannot extract a date because
all present date headers are in an unrecognisable format, AWS4Auth
will delete any X-Amz-Date
and Date
headers present and replace with
a single X-Amz-Date
header containing the current date. This behaviour
can be modified using the raise_invalid_date
keyword argument of the
AWS4Auth
constructor.
If you do not want the signing key to be automatically regenerated when
a mismatch between the request date and the scope date is encountered,
use the alternative StrictAWS4Auth
class, which is identical to
AWS4Auth
except that upon encountering a date mismatch it just raises
a DateMismatchError
. You can also use the PassiveAWS4Auth
class,
which mimics the AWS4Auth
behaviour prior to version 0.8 and just
signs and sends the request, whether the date matches or not. In this
case it is up to the calling code to handle an authentication failure
response from AWS caused by the date mismatch.
To allow automatic key regeneration, the secret key is stored in the
AWS4Auth
instance, in the signing key object. If you do not want this
to occur, instantiate the instance using an AWS4Signing
key which was
created with the store_secret_key
parameter set to False:
>>> sig_key = AWS4SigningKey(secret_key, region, service, date, False)
>>> auth = StrictAWS4Auth(access_id, sig_key)
The AWS4Auth
class will then raise a NoSecretKeyError
when it
attempts to regenerate its key. A slightly more conceptually elegant way
to handle this is to use the alternative StrictAWS4Auth
class, again
instantiating it with an AWS4SigningKey
instance created with
store_secret_key = False
.
If you share AWS4Auth
(or even StrictAWS4Auth
) instances between
threads you are likely to encounter problems. Because AWS4Auth
instances may unpredictably regenerate their signing key as part of
signing a request, threads using the same instance may find the key
changed by another thread halfway through the signing process, which may
result in undefined behaviour.
It may be possible to rig up a workable instance sharing mechanism using
locking primitives and the StrictAWS4Auth
class, however this poor
author can't think of a scenario which works safely yet doesn't suffer
from at some point blocking all threads for at least the duration of an
HTTP request, which could be several seconds. If several requests come
in in close succession which all require key regenerations then the
system could be forced into serial operation for quite a length of time.
In short, it's probably best to create a thread-local instance of
AWS4Auth
for each thread that needs to do authentication.
See the doctrings in aws4auth.py
and aws4signingkey.py
.
A test suite is included in the test folder.
The package passes all tests in the AWS auth v4
test_suite,
and contains tests against the supported live services. See docstrings
in test/requests_aws4auth_test.py
for details about running the tests.
Connection parameters are included in the tests for the AWS Support API, should you have access and want to try it. The documentation says it supports auth v4 so it should work if you have a subscription. Do pass on your results!
HISTORY.md
requests_aws4auth/__init__.py
docker env:
docker run -v `pwd`:/opt/app/ -v ~/.pypirc:/root/.pypirc -it python:3.12 /bin/bash
prep:
python3 -m pip install --user --upgrade setuptools wheel testresources twine
build and release, creds in ~/.pypirc
:
rm -f dist/*; \
python3 setup.py sdist bdist_wheel && \
python3 -m twine upload --repository testpypi dist/* && \
python3 -m twine upload --repository pypi dist/*
Changes
Changes
six
and support for any python before 3.7, #73. Thanks @hugovk.Changes
Bugfixes
Bugfixes
Bugfixes
Changes
Changes
Bugfixes
Package changes
Tests
New features
amz_norm_whitespace
. shlex doesn't like to split whitespace on a string without whitespace, taking several orders of magnitude longer to parse through it. #35, thanks @noamkush.refreshable_credentials
, see #37, thanks @teemuy.Package changes
Requires-Python
will be set to py3.3+ in the next minor release.Tests
New features
Package changes
Tests
New features
Package changes
Tests
New features
Tests
AWS4SigningKey.amz_date
deprecation warning testThis version introduces some behaviour changes designed to reduce the legwork needed when a signing key goes out of date. This has implications for multithreading and secret key storage. See the README for further details.
New features
AWS4Auth changes
regenerate_signing_key()
method, to allow regeneration of
current signing key with parameter overridesget_request_date()
, parse_date()
, handle_date_mismatch()
__call__()
now checks for a date header in the request and
attempts to automatically regenerate the signing key with the
request date if request date differs from the signing key dateDate
header if
presentAWS4SigningKey changes
store_secret_key
instantiation parameter which allows
control of whether the secret key is stored in the instanceamz_date
property in favour of just date
Package changes
Tests
Bugfixes
b''
during signing if it's NoneModules
Tests
Bugfixes
Bugfixes
x-amz-*
headers (except for
x-amz-client-context which breaks Mobile Analytics auth if included)Docs
License
FAQs
AWS4 authentication for Requests
We found that requests-aws4auth demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.