Skip to content

Instantly share code, notes, and snippets.

@scragg0x
Created September 17, 2012 17:56
Show Gist options
  • Save scragg0x/3738771 to your computer and use it in GitHub Desktop.
Save scragg0x/3738771 to your computer and use it in GitHub Desktop.
Tornados Signed Value Functions
def _time_independent_equals(a, b):
if len(a) != len(b):
return False
result = 0
if type(a[0]) is int: # python3 byte strings
for x, y in zip(a, b):
result |= x ^ y
else: # python2
for x, y in zip(a, b):
result |= ord(x) ^ ord(y)
return result == 0
def create_signed_value(secret, name, value):
timestamp = utf8(str(int(time.time())))
value = base64.b64encode(utf8(value))
signature = _create_signature(secret, name, value, timestamp)
value = b("|").join([value, timestamp, signature])
return value
def decode_signed_value(secret, name, value, max_age_days=31):
if not value:
return None
parts = utf8(value).split(b("|"))
if len(parts) != 3:
return None
signature = _create_signature(secret, name, parts[0], parts[1])
if not _time_independent_equals(parts[2], signature):
logging.warning("Invalid cookie signature %r", value)
return None
timestamp = int(parts[1])
if timestamp < time.time() - max_age_days * 86400:
logging.warning("Expired cookie %r", value)
return None
if timestamp > time.time() + 31 * 86400:
# _cookie_signature does not hash a delimiter between the
# parts of the cookie, so an attacker could transfer trailing
# digits from the payload to the timestamp without altering the
# signature. For backwards compatibility, sanity-check timestamp
# here instead of modifying _cookie_signature.
logging.warning("Cookie timestamp in future; possible tampering %r", value)
return None
if parts[1].startswith(b("0")):
logging.warning("Tampered cookie %r", value)
return None
try:
return base64.b64decode(parts[0])
except Exception:
return None
def _create_signature(secret, *parts):
hash = hmac.new(utf8(secret), digestmod=hashlib.sha1)
for part in parts:
hash.update(utf8(part))
return utf8(hash.hexdigest())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment