Skip to content

Commit

Permalink
fix regression with code expecting secrets to be encoded with latin-1
Browse files Browse the repository at this point in the history
  • Loading branch information
mmerickel committed Feb 22, 2014
1 parent b2c2395 commit cf026e2
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
16 changes: 12 additions & 4 deletions pyramid/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ def signed_serialize(data, secret):
response.set_cookie('signed_cookie', cookieval)
"""
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
sig = hmac.new(bytes_(secret, 'utf-8'), pickled, hashlib.sha1).hexdigest()
try:
# bw-compat with pyramid <= 1.5b1 where latin1 is the default
secret = bytes_(secret)
except UnicodeEncodeError:
secret = bytes_(secret, 'utf-8')
sig = hmac.new(secret, pickled, hashlib.sha1).hexdigest()
return sig + native_(base64.b64encode(pickled))

def signed_deserialize(serialized, secret, hmac=hmac):
Expand All @@ -81,9 +86,12 @@ def signed_deserialize(serialized, secret, hmac=hmac):
# Badly formed data can make base64 die
raise ValueError('Badly formed base64 data: %s' % e)

sig = bytes_(hmac.new(
bytes_(secret, 'utf-8'), pickled, hashlib.sha1,
).hexdigest())
try:
# bw-compat with pyramid <= 1.5b1 where latin1 is the default
secret = bytes_(secret)
except UnicodeEncodeError:
secret = bytes_(secret, 'utf-8')
sig = bytes_(hmac.new(secret, pickled, hashlib.sha1).hexdigest())

# Avoid timing attacks (see
# http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf)
Expand Down
17 changes: 15 additions & 2 deletions pyramid/tests/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,10 +533,16 @@ def test_it(self):
self.assertEqual(result, expected)

def test_it_with_highorder_secret(self):
secret = b'La Pe\xc3\xb1a'.decode('utf-8')
secret = b'\xce\xb1\xce\xb2\xce\xb3\xce\xb4'.decode('utf-8')
expected = serialize('123', secret)
result = self._callFUT('123', secret)
self.assertEqual(result, expected)

def test_it_with_latin1_secret(self):
secret = b'La Pe\xc3\xb1a'
expected = serialize('123', secret)
result = self._callFUT('123', secret.decode('latin-1'))
self.assertEqual(result, expected)

class Test_signed_deserialize(unittest.TestCase):
def _callFUT(self, serialized, secret, hmac=None):
Expand Down Expand Up @@ -569,11 +575,18 @@ def test_it_bad_encoding(self):
self.assertRaises(ValueError, self._callFUT, serialized, 'secret')

def test_it_with_highorder_secret(self):
secret = b'La Pe\xc3\xb1a'.decode('utf-8')
secret = b'\xce\xb1\xce\xb2\xce\xb3\xce\xb4'.decode('utf-8')
serialized = serialize('123', secret)
result = self._callFUT(serialized, secret)
self.assertEqual(result, '123')

# bwcompat with pyramid <= 1.5b1 where latin1 is the default
def test_it_with_latin1_secret(self):
secret = b'La Pe\xc3\xb1a'
serialized = serialize('123', secret)
result = self._callFUT(serialized, secret.decode('latin-1'))
self.assertEqual(result, '123')

class Test_check_csrf_token(unittest.TestCase):
def _callFUT(self, *args, **kwargs):
from ..session import check_csrf_token
Expand Down

0 comments on commit cf026e2

Please sign in to comment.