Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Avoid timing attacks in AuthTktAutenticationPolicy #320

Merged
merged 1 commit into from

2 participants

@rfk

This factors out the timing-invariant string comparison code from
session.py and re-uses it for signature checking in AuthTkt code.

@rfk rfk Avoid timing attacks in AuthTktAutenticationPolicy
This factors out the timing-invariant string comparison code from
session.py and re-uses it for signature checking in AuthTkt code.
13906d6
@mcdonc mcdonc merged commit d1527f4 into Pylons:master
@mcdonc
Owner

Thank you!

@biosyssun biosyssun referenced this pull request from a commit in biosyssun/pyramid
@mcdonc mcdonc - The AuthTktAuthenticationPolicy did not use a timing-attack-aware s…
…tring

  comparator.  See Pylons/pyramid#320 for more info.

References issue#320.
e61ab86
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 15, 2011
  1. @rfk

    Avoid timing attacks in AuthTktAutenticationPolicy

    rfk authored
    This factors out the timing-invariant string comparison code from
    session.py and re-uses it for signature checking in AuthTkt code.
This page is out of date. Refresh to see the latest.
Showing with 28 additions and 10 deletions.
  1. +5 −1 pyramid/authentication.py
  2. +3 −9 pyramid/session.py
  3. +20 −0 pyramid/util.py
View
6 pyramid/authentication.py
@@ -22,6 +22,8 @@
from pyramid.security import Authenticated
from pyramid.security import Everyone
+from pyramid.util import strings_differ
+
VALID_TOKEN = re.compile(r"^[A-Za-z][A-Za-z0-9+_-]*$")
class CallbackAuthenticationPolicy(object):
@@ -485,7 +487,9 @@ def parse_ticket(secret, ticket, ip):
expected = calculate_digest(ip, timestamp, secret,
userid, tokens, user_data)
- if expected != digest:
+ # Avoid timing attacks (see
+ # http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf)
+ if strings_differ(expected, digest):
raise BadTicket('Digest signature is not correct',
expected=(expected, digest))
View
12 pyramid/session.py
@@ -13,6 +13,7 @@
from pyramid.compat import bytes_
from pyramid.compat import native_
from pyramid.interfaces import ISession
+from pyramid.util import strings_differ
def manage_accessed(wrapped):
""" Decorator which causes a cookie to be set when a wrapped
@@ -262,17 +263,10 @@ def signed_deserialize(serialized, secret, hmac=hmac):
sig = hmac.new(bytes_(secret), pickled, sha1).hexdigest()
- if len(sig) != len(input_sig):
- raise ValueError('Wrong signature length')
-
# Avoid timing attacks (see
# http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf)
- invalid_bits = 0
- for a, b in zip(sig, input_sig):
- invalid_bits += a != b
-
- if invalid_bits:
- raise ValueError('Invalid bits in signature')
+ if strings_differ(sig, input_sig):
+ raise ValueError('Invalid signature')
return pickle.loads(pickled)
View
20 pyramid/util.py
@@ -208,3 +208,23 @@ def last(self):
oid = self._order[-1]
return self._items[oid]()
+def strings_differ(string1, string2):
+ """Check whether two strings differ while avoiding timing attacks.
+
+ This function returns True if the given strings differ and False
+ if they are equal. It's careful not to leak information about *where*
+ they differ as a result of its running time, which can be very important
+ to avoid certain timing-related crypto attacks:
+
+ http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf
+
+ """
+ if len(string1) != len(string2):
+ return True
+
+ invalid_bits = 0
+ for a, b in zip(string1, string2):
+ invalid_bits += a != b
+
+ return invalid_bits != 0
+
Something went wrong with that request. Please try again.