From 2f797003cd560f5492d4f9d75f87d7bb8433cb58 Mon Sep 17 00:00:00 2001 From: Eeo Jun Date: Sun, 22 May 2016 16:36:21 +0800 Subject: [PATCH 1/3] Don't reveal string length to attacker. --- src/pyotp/utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pyotp/utils.py b/src/pyotp/utils.py index f816703..47ee0fa 100644 --- a/src/pyotp/utils.py +++ b/src/pyotp/utils.py @@ -1,6 +1,10 @@ from __future__ import print_function, unicode_literals, division, absolute_import import unicodedata +try: + from itertools import izip_longest +except ImportError: + from itertools import zip_longest as izip_longest try: from urllib.parse import quote @@ -77,6 +81,6 @@ def strings_equal(s1, s2): return False differences = 0 - for c1, c2 in zip(s1, s2): + for c1, c2 in izip_longest(s1, s2, '\0'): differences |= ord(c1) ^ ord(c2) return differences == 0 From 7ccb5197c347bd5216bcfa1d7306745b14cfe051 Mon Sep 17 00:00:00 2001 From: Eeo Jun Date: Sun, 22 May 2016 16:40:18 +0800 Subject: [PATCH 2/3] Remove "short circuit" section --- src/pyotp/utils.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pyotp/utils.py b/src/pyotp/utils.py index 47ee0fa..7215770 100644 --- a/src/pyotp/utils.py +++ b/src/pyotp/utils.py @@ -77,9 +77,6 @@ def strings_equal(s1, s2): except ImportError: pass - if len(s1) != len(s2): - return False - differences = 0 for c1, c2 in izip_longest(s1, s2, '\0'): differences |= ord(c1) ^ ord(c2) From fa4a70f9a3757858548affbaacdb77e5573fa8b2 Mon Sep 17 00:00:00 2001 From: Eeo Jun Date: Sun, 22 May 2016 17:18:05 +0800 Subject: [PATCH 3/3] Use None instead of \0 character as sentinel --- src/pyotp/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pyotp/utils.py b/src/pyotp/utils.py index 7215770..d863da2 100644 --- a/src/pyotp/utils.py +++ b/src/pyotp/utils.py @@ -78,6 +78,8 @@ def strings_equal(s1, s2): pass differences = 0 - for c1, c2 in izip_longest(s1, s2, '\0'): + for c1, c2 in izip_longest(s1, s2): + if c1 is None or c2 is None: + pass differences |= ord(c1) ^ ord(c2) return differences == 0