diff options
author | Jeff Lindsay <progrium@gmail.com> | 2013-06-15 12:20:06 -0700 |
---|---|---|
committer | Jeff Lindsay <progrium@gmail.com> | 2013-06-15 12:20:06 -0700 |
commit | 6d7d9a48bd42c17fd2fb548e85e527ed96865b12 (patch) | |
tree | 13ef07316021b6c27ab3c4373bd1eb97ecf54635 | |
parent | 747b8b27101b6927e8c35ec4520020b81b3606c9 (diff) | |
parent | 254125a7478e3fe4d7518d83b82d03399fd2eef3 (diff) | |
download | pyjwt-6d7d9a48bd42c17fd2fb548e85e527ed96865b12.tar.gz |
Merge pull request #13 from Lothiraldan/constant_time_compare
Use a constant time compare for comparing signatures. Fix #7
-rw-r--r-- | jwt/__init__.py | 17 |
1 files changed, 16 insertions, 1 deletions
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") |