Created
July 18, 2014 15:26
-
-
Save gavinballard/95995f013c81e74395f8 to your computer and use it in GitHub Desktop.
Python methods to verify the signature of a request being sent through a Shopify application proxy.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hashlib, base64, hmac | |
def get_proxy_signature(query_dict, secret): | |
""" | |
Calculate the signature of the given query dict as per Shopify's documentation for proxy requests. | |
See: http://docs.shopify.com/api/tutorials/application-proxies#security | |
""" | |
# Sort and combine query parameters into a single string. | |
sorted_params = '' | |
for key in sorted(query_dict.keys()): | |
sorted_params += "{0}={1}".format(key, ",".join(query_dict.getlist(key))) | |
signature = hmac.new(secret, sorted_params, hashlib.sha256) | |
return signature.hexdigest() | |
def proxy_signature_is_valid(request, secret): | |
""" | |
Return true if the calculated signature matches that present in the query string of the given request. | |
""" | |
# Create a mutable version of the GET parameters. | |
query_dict = request.GET.copy() | |
# Extract the signature we're going to verify. If no signature's present, the request is invalid. | |
try: | |
signature_to_verify = query_dict.pop('signature')[0] | |
except KeyError: | |
return False | |
calculated_signature = get_proxy_signature(query_dict, secret) | |
# Try to use compare_digest() to reduce vulnerability to timing attacks. | |
# If it's not available, just fall back to regular string comparison. | |
try: | |
return hmac.compare_digest(calculated_signature, signature_to_verify) | |
except AttributeError: | |
return calculated_signature == signature_to_verify |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment