From 254125a7478e3fe4d7518d83b82d03399fd2eef3 Mon Sep 17 00:00:00 2001 From: FELD Boris Date: Fri, 14 Jun 2013 10:11:43 +0200 Subject: Use a constant time compare for comparing signatures. Fix #7 --- jwt/__init__.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/jwt/__init__.py b/jwt/__init__.py index 2178d47..2cd16ca 100644 --- a/jwt/__init__.py +++ b/jwt/__init__.py @@ -34,6 +34,20 @@ signing_methods = { } +def constant_time_compare(val1, val2): + """ + Returns True if the two strings are equal, False otherwise. + + The time taken is independent of the number of characters that match. + """ + if len(val1) != len(val2): + return False + result = 0 + for x, y in zip(val1, val2): + result |= ord(x) ^ ord(y) + return result == 0 + + def base64url_decode(input): rem = len(input) % 4 if rem > 0: @@ -107,7 +121,8 @@ def decode(jwt, key='', verify=True, verify_expiration=True, leeway=0): try: if isinstance(key, unicode): key = key.encode('utf-8') - if not signature == signing_methods[header['alg']](signing_input, key): + expected = signing_methods[header['alg']](signing_input, key) + if not constant_time_compare(signature, expected): raise DecodeError("Signature verification failed") except KeyError: raise DecodeError("Algorithm not supported") -- cgit v1.2.1