Giter VIP home page Giter VIP logo

requests-http-signature's People

Contributors

arjenjb avatar boh717 avatar epicfaace avatar georgkrause avatar jhenligne avatar kennethreitz avatar kevingill1966 avatar kislyuk avatar metarizard avatar romanek-adam-b2c2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

requests-http-signature's Issues

Voice implementer support for HTTP Signatures in IETF HTTP WG

Hi, I'm @msporny, primary author of the HTTP Signatures specification at IETF for many years now. You've implemented some variation of that specification.

I need your help to move that specification towards a global standard at IETF. Hearing from implementers, such as you, is a big part of determining if the work toward a global standard should proceed. The IETF HTTP Working Group is determining whether the work should proceed right now. This is very good news, because the European Banking API community, W3C DID Working Group, W3C Credentials Community Group and other standards setting organizations depend on implementations standardizing on a way to do HTTP Signatures.

The deadline for noting your support is Jan 31st 2020 (in ~10 days).

Here's where you can make a difference...

Here is the IETF HTTP WG Call for Adoption:

https://lists.w3.org/Archives/Public/ietf-http-wg/2020JanMar/0002.html

To note your support of the specification:

  1. Go here and click "subscribe to this list": https://lists.w3.org/Archives/Public/ietf-http-wg/
  2. Verify your subscription by checking your email and clicking on the link that is mailed to you.
  3. Go here and click "respond to this message": https://lists.w3.org/Archives/Public/ietf-http-wg/2020JanMar/0002.html
  4. Write an email stating:
    4.1 That you support the adoption of the draft.
    4.2 Why you support the adoption of the draft.
    4.3 How you plan to make use the specification, either directly, or indirectly (via someone else's software).
  5. Set up an email filter to put all mail sent to [email protected] into its own folder. The mailing list averages ~350 emails/month. You can also leave the mailing list immediately after sending the email above if that amount of email traffic is unacceptable to you.

For an example of the type of email you could write, see this:

https://lists.w3.org/Archives/Public/ietf-http-wg/2020JanMar/0018.html

Thanks a ton for supporting the specification through your implementation. I hope you consider helping us take the specification across the goal line by voicing your support in the IETF HTTP Working Group!

Another release

Hi and thanks for working on this library!

There's a couple changes that have been merged in since the 0.2.0 release that I'd like to make use of in a project of mine.
Would it be possible to push a new release to pypi that has those changes?

Thanks again!

A couple feature proposals (willing to implement, but want feedback first)

Hello!

I am working on a project involving requests-oauthlib and this library. And i have run into some bugs/issues. For these i have provided possible fixes that i am willing to make a PR for after having recieved feedback.

1 An empty body leads to error:
File "[omitted]/python3.7/site-packages/requests/structures.py", line 54, in __getitem__ return self._store[key.lower()][1] KeyError: 'digest'
My current workaround: Override add_digest, and build in check:

class MyHTTPSignatureAuth(HTTPSignatureAuth):
    def add_digest(self, request):
        if not request.body:
            # Since the message body (payload) is empty, the digest is defaulted to the hash256 of an empty body.
            request.headers["Digest"] = "SHA-256=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="
        else:
            return super(MyHTTPSignatureAuth, self).__call__(request)

Suggested change: Build check into the actual code

2 Incorrect body encoding leads to error:
File "[omitted]/python3.7/site-packages/requests_http_signature/__init__.py", line 73, in add_digest digest = self.hasher_constructor(request.body).digest() TypeError: Unicode-objects must be encoded before hashing
My current workaround: Override add_digest, and encode to utf-8:

class MyHTTPSignatureAuth(HTTPSignatureAuth):
    def add_digest(self, request):
        if request.body:
            request.body=request.body.encode('utf-8')
        super(MyHTTPSignatureAuth, self).add_digest(request)

Suggested change: This workaround probably wouldn't translate into a fix directly as utf-8 is not always the desired encoding (i think). Though i dont understand enough about the crypto and http standard to be sure of this. If multiple encodings should be supported, the option should be added somewhere, if not, we should always convert to utf-8
Note: In python3 everything is unicode thus this error will happen by default, always.

3 Doesn't play nice with token authorization
This auth lib works when requesting auth tokens because is sets the Authorization header. However when signing subsequent messages, the Authorization header should be the token, and the Signature should be specified in the Signature header
My current workaround: Override __call__, and build check for preexisting Authorization field:

class MyHTTPSignatureAuth(HTTPSignatureAuth):
    def __call__(self, request):
        if "Authorization" in request.headers:
            auth = request.headers["Authorization"]
            req = super(MyHTTPSignatureAuth, self).__call__(request)
            req.headers["Signature"]=req.headers["Authorization"].split(' ', 1)[1]
            req.headers["Authorization"]=auth
            return req
        else:
            return super(MyHTTPSignatureAuth, self).__call__(request)

Suggested change: Unclear. I don't know if adding the Signature field even is the intended purpose of the library. I don't know when the Signature header should be used over the Authorization header. For a fix i would probably lean towards providing an option in the constructor to set Signature instead of Authorization, or maybe go with the dirty code in the work around if it doen't cause any issues.

Any thoughts on these changes? Should i implement them in a PR?

P.s: here is the whole class i am using at the moment:

class MyHTTPSignatureAuth(HTTPSignatureAuth):
    def __call__(self, request):
        if "Authorization" in request.headers:
            auth = request.headers["Authorization"]
            req = super(MyHTTPSignatureAuth, self).__call__(request)
            req.headers["Signature"]=req.headers["Authorization"].split(' ', 1)[1]
            req.headers["Authorization"]=auth
            return req
        else:
            return super(MyHTTPSignatureAuth, self).__call__(request)


    def add_digest(self, request):
        if request.body:
            request.body=request.body.encode('utf-8')
            super(MyHTTPSignatureAuth, self).add_digest(request)
        else:
            super(MyHTTPSignatureAuth, self).add_digest(request)
            return
            # Since the message body (payload) is empty, the digest is defaulted to the hash256 of an empty body.
            request.headers["Digest"] = "SHA-256=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="

Address multiple field value header security discussion in draft 11

7.23.  Non-List Field Values

   When an HTTP field occurs multiple times in a single message, these
   values need to be combined into a single one-line string value to be
   included in the HTTP signature base, as described in Section 2.4.
   Not all HTTP fields can be combined into a single value in this way
   and still be a valid value for the field.  For the purposes of
   generating the signature base, the message component value is never
   meant to be read back out of the signature base string or used in the
   application.  Therefore it is considered best practice to treat the
   signature base generation algorithm separately from processing the
   field values by the application, particularly for fields that are
   known to have this property.  If the field values that are being
   signed do not validate, the signed message should also be rejected.

   If an HTTP field allows for unquoted commas within its values,
   combining multiple field values can lead to a situation where two
   semantically different messages produce the same line in a signature
   base.  For example, take the following hypothetical header field with
   an internal comma in its syntax, here used to define two separate
   lists of values:

   Example-Header: value, with, lots
   Example-Header: of, commas

   For this header field, sending all of these values as a single field
   value results in a single list of values:

   Example-Header: value, with, lots, of, commas

   Both of these messages would create the following line in the
   signature base:

   "example-header": value, with, lots, of, commas

   Since two semantically distinct inputs can create the same output in
   the signature base, special care has to be taken when handling such
   values.

   Specifically, the Set-Cookie field [COOKIE] defines an internal
   syntax that does not conform to the List syntax in
   [STRUCTURED-FIELDS].  In particular some portions allow unquoted
   commas, and the field is typically sent as multiple separate field
   lines with distinct values when sending multiple cookies.  When
   multiple Set-Cookie fields are sent in the same message, it is not
   generally possible to combine these into a single line and be able to
   parse and use the results, as discussed in [HTTP], Section 5.3.
   Therefore, all the cookies need to be processed from their separate
   header values, without being combined, while the signature base needs
   to be processed from the special combined value generated solely for
   this purpose.  If the cookie value is invalid, the signed message
   ought to be rejected as this is a possible padding attack as
   described in Section 7.24.

   To deal with this, an application can choose to limit signing of
   problematic fields like Set-Cookie, such as including the field in a
   signature only when a single field value is present and the results
   would be unambiguous.  Similar caution needs to be taken with all
   fields that could have non-deterministic mappings into the signature
   base.  Signers can also make use of the bs parameter to armor such
   fields, as described in Section 2.1.3.

7.24.  Padding Attacks with Multiple Field Values

   Since HTTP field values need to be combined in a single string value
   to be included in the HTTP signature base, as described in
   Section 2.4, it is possible for an attacker to inject an additional
   value for a given field and add this to the signature base of the
   verifier.

   In most circumstances, this causes the signature validation to fail
   as expected, since the new signature base value will not match the
   one used by the signer to create the signature.  However, it is
   theoretically possible for the attacker to inject both a garbage
   value to a field and a desired value to another field in order to
   force a particular input.  This is a variation of the collision
   attack described in Section 7.5, where the attacker accomplishes
   their change in the message by adding to existing field values.

   To counter this, an application needs to validate the content of the
   fields covered in the signature in addition to ensuring that the
   signature itself validates.  With such protections, the attacker's
   padding attack would be rejected by the field value processor, even
   in the case where the attacker could force a signature collision.

Asymmetric key full example

Hi, thanks a lot for writing this library. I'm trying to setup HTTP signatures using RSA but I'm struggling to get it working. Could you please add an example of key_resolver() with RSA in the README?
Thank you!

CryptographyDeprecationWarning

Hello, I am getting the following warning:

requests_http_signature/__init__.py:25: CryptographyDeprecationWarning: signer and verifier have been deprecated. Please use sign and verify instead.
  signer = key.signer(padding=self.PKCS1v15(), algorithm=hasher)

I happened in the following code:

with open('certs/example_client_signing.key', 'rb') as fh:                                                               
    auth=MyHTTPSignatureAuth(algorithm="rsa-sha256", headers=[ '(request-target)', 'date', 'digest' ], key=fh.read(), key_id=client_id)

i am using Python 3.5.3

New release

Hi, and thank you for working on this library.
I was wondering, since the current release on pypi is 0.1.0 (from 2018), if it was possible to publish even a minor release update in order to get the package on pypi up to date with the last changes. Thank you.

Support httpx

HTTPX tries to be compatible with the requests package, including the use of callables for custom authentication. However, it is incompatible with requests_http_signature. When trying to sign a request, this is the error: AttributeError: 'Request' object has no attribute 'body'

requests_http_signature expects the body attribute here, but the Request object does not have the attribute because it is called content.

What I don't understand is that the Request object of the Requests library also seems to have no attribute called body. Why does it work here then?

Link to empty Flask-http-signature repo?

Hi I'm just trying to get started with this library, thanks much for it. Noticed that this link in README.rst takes me to an empty repo:

https://github.com/pyauth/flask-http-signature

I don't know your plans for that repo, just wanted to check if you might want to add some text here?

Cannot verify "host" with HTTPSignatureAuth

When using host in headers= with HTTPSignatureAuth, the signature does not validate.

Example:

  • makes valid signature: headers=[ '(request-target)', 'date', 'digest' ]
  • makes not valid signature: headers=[ '(request-target)', 'host', 'date', 'digest' ]

I cannot test HTTPSignatureHeaderAuth because there is not verify method available.

Add HTTPSignatureHeaderAuth.verify()

The class HTTPSignatureHeaderAuth inherits the method verify() that uses the default scheme="Authorization". It would be nice to override this method such that scheme="Signature" is set automatically:

class HTTPSignatureHeaderAuth(HTTPSignatureAuth):
    def verify(self, request, key_resolver):
        return super().verify(request, key_resolver, scheme="Signature")

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.