diff options
author | Hoylen Sue <hoylen@hoylen.com> | 2019-02-19 20:51:49 +1000 |
---|---|---|
committer | Hoylen Sue <hoylen@hoylen.com> | 2019-02-19 20:51:49 +1000 |
commit | 0ef0a9c4342dfee4bd3aef7d6d9fa09e7226a732 (patch) | |
tree | 0b6e50fb98808002dd50d87d370b7b90804912c2 /oauthlib/oauth1 | |
parent | b4d0d1ec86e401c44ea7c8fc09b49aea9ba6ebf2 (diff) | |
download | oauthlib-0ef0a9c4342dfee4bd3aef7d6d9fa09e7226a732.tar.gz |
Fixed space encoding in base string URI used in the signature base string.
Diffstat (limited to 'oauthlib/oauth1')
-rw-r--r-- | oauthlib/oauth1/rfc5849/signature.py | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/oauthlib/oauth1/rfc5849/signature.py b/oauthlib/oauth1/rfc5849/signature.py index e90d6f3..589b68a 100644 --- a/oauthlib/oauth1/rfc5849/signature.py +++ b/oauthlib/oauth1/rfc5849/signature.py @@ -105,9 +105,9 @@ def construct_base_string(http_method, base_string_uri, return base_string -def normalize_base_string_uri(uri, host=None): +def base_string_uri(uri, host=None): """**Base String URI** - Per `section 3.4.1.2`_ of the spec. + Per `section 3.4.1.2`_ of RFC 5849. For example, the HTTP request:: @@ -177,7 +177,31 @@ def normalize_base_string_uri(uri, host=None): if (scheme, port) in default_ports: netloc = host - return urlparse.urlunparse((scheme, netloc, path, params, '', '')) + v = urlparse.urlunparse((scheme, netloc, path, params, '', '')) + + # RFC 5849 does not specify which characters are encoded in the + # "base string URI", nor how they are encoded - which is very bad, since + # the signatures won't match if there are any differences. Fortunately, + # most URIs only use characters that are clearly not encoded (e.g. digits + # and A-Z, a-z), so have avoided any differences between implementations. + # + # The example from its section 3.4.1.2 illustrates that spaces in + # the path are percent encoded. But it provides no guidance as to what other + # characters (if any) must be encoded (nor how); nor if characters in the + # other components are to be encoded or not. + # + # This implementation **assumes** that **only** the space is percent-encoded + # and it is done to the entire value (not just to spaces in the path). + # + # This code may need to be changed if it is discovered that other characters + # are expected to be encoded. + # + # Note: the "base string URI" returned by this function will be encoded + # again before being concatenated into the "signature base string". So any + # spaces in the URI will actually appear in the "signature base string" + # as "%2520" (the "%20" further encoded according to section 3.6). + + return v.replace(' ', '%20') # ** Request Parameters ** @@ -624,8 +648,8 @@ def verify_hmac_sha1(request, client_secret=None, """ norm_params = normalize_parameters(request.params) - uri = normalize_base_string_uri(request.uri) - base_string = construct_base_string(request.http_method, uri, norm_params) + bs_uri = base_string_uri(request.uri) + base_string = construct_base_string(request.http_method, bs_uri, norm_params) signature = sign_hmac_sha1(base_string, client_secret, resource_owner_secret) match = safe_string_equals(signature, request.signature) @@ -657,8 +681,8 @@ def verify_rsa_sha1(request, rsa_public_key): .. _`RFC2616 section 5.2`: https://tools.ietf.org/html/rfc2616#section-5.2 """ norm_params = normalize_parameters(request.params) - uri = normalize_base_string_uri(request.uri) - message = construct_base_string(request.http_method, uri, norm_params).encode('utf-8') + bs_uri = base_string_uri(request.uri) + message = construct_base_string(request.http_method, bs_uri, norm_params).encode('utf-8') sig = binascii.a2b_base64(request.signature.encode('utf-8')) alg = _jwt_rs1_signing_algorithm() |