From cf8b0d1f134dd4548abaea03e373811c8155ee24 Mon Sep 17 00:00:00 2001 From: Stian Prestholdt Date: Tue, 21 Oct 2014 13:52:39 +0200 Subject: [PATCH] Add Python 3 support for FacebookAuthorization.parse_signed_data `json.loads` was expecting a string, but in python 3 `base64decode()` return bytes and that is why it bugged. We fix this by making sure the decoded payload data is in string and that `hmac.new()` is provided with arguments in bytes. `open_facebook.utils.smart_str` will do that job correctly in python 2 and 3. We also use `hmac.compare_digest()` which is the preferred way to compare those kinds of data to prevent timing analysis. Read more about this on python docs. Though this is only available from python 2.7.7. Fixes #491. --- open_facebook/api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/open_facebook/api.py b/open_facebook/api.py index b023e018..67385319 100644 --- a/open_facebook/api.py +++ b/open_facebook/api.py @@ -464,7 +464,7 @@ def parse_signed_data(cls, signed_request, and http://sunilarora.org/parsing-signedrequest-parameter-in-python-bas ''' - from open_facebook.utils import base64_url_decode_php_style + from open_facebook.utils import base64_url_decode_php_style, smart_str l = signed_request.split('.', 2) encoded_sig = l[0] payload = l[1] @@ -472,7 +472,7 @@ def parse_signed_data(cls, signed_request, sig = base64_url_decode_php_style(encoded_sig) import hmac import hashlib - data = json.loads(base64_url_decode_php_style(payload)) + data = json.loads(base64_url_decode_php_style(payload).decode('utf-8')) algo = data.get('algorithm').upper() if algo != 'HMAC-SHA256': @@ -482,10 +482,10 @@ def parse_signed_data(cls, signed_request, logger.error('Unknown algorithm') return None else: - expected_sig = hmac.new(secret, msg=payload, + expected_sig = hmac.new(smart_str(secret), msg=smart_str(payload), digestmod=hashlib.sha256).digest() - if sig != expected_sig: + if not hmac.compare_digest(sig, expected_sig): error_format = 'Signature %s didnt match the expected signature %s' error_message = error_format % (sig, expected_sig) send_warning(error_message)