Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added validation of signature without stripping port number #477

Merged
merged 8 commits into from
Sep 25, 2019
34 changes: 30 additions & 4 deletions twilio/request_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@ def remove_port(uri):
return new_uri.geturl()


def add_port(uri, port):
"""Add the port number to a URI

:param uri: full URI that Twilio requested on your server
:param port: the port number to be added to the URI
eshanholtz marked this conversation as resolved.
Show resolved Hide resolved

:returns: full URI with a port number
:rtype: str
"""
new_netloc = uri.netloc + ":" + str(port)
new_uri = uri._replace(netloc=new_netloc)
return new_uri.geturl()


class RequestValidator(object):

def __init__(self, token):
Expand Down Expand Up @@ -82,17 +96,29 @@ def validate(self, uri, params, signature):
params = {}

parsed_uri = urlparse(uri)
uri_with_port = uri
uri_without_port = uri

if parsed_uri.scheme == "https" and parsed_uri.port:
uri = remove_port(parsed_uri)
uri_without_port = remove_port(parsed_uri)
elif parsed_uri.scheme == "https":
uri_with_port = add_port(parsed_uri, 443)
elif parsed_uri.scheme == "http" and parsed_uri.port:
uri_without_port = remove_port(parsed_uri)
elif parsed_uri.scheme == "http":
uri_with_port = add_port(parsed_uri, 80)
childish-sambino marked this conversation as resolved.
Show resolved Hide resolved

valid_signature = False # Default fail
valid_signature_with_port = False
valid_body_hash = True # May not receive body hash, so default succeed

query = parse_qs(parsed_uri.query)
if "bodySHA256" in query and isinstance(params, string_types):
valid_body_hash = compare(self.compute_hash(params), query["bodySHA256"][0])
valid_signature = compare(self.compute_signature(uri, {}), signature)
valid_signature = compare(self.compute_signature(uri_without_port, {}), signature)
childish-sambino marked this conversation as resolved.
Show resolved Hide resolved
valid_signature_with_port = compare(self.compute_signature(uri_with_port, {}), signature)
else:
valid_signature = compare(self.compute_signature(uri, params), signature)
valid_signature = compare(self.compute_signature(uri_without_port, params), signature)
valid_signature_with_port = compare(self.compute_signature(uri_with_port, params), signature)

return valid_signature and valid_body_hash
return valid_body_hash and (valid_signature or valid_signature_with_port)