summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt3
-rw-r--r--docs/quick_tutorial/hello_world.rst4
-rw-r--r--docs/quick_tutorial/hello_world/app.py4
-rw-r--r--pyramid/session.py14
-rw-r--r--pyramid/tests/test_session.py27
5 files changed, 45 insertions, 7 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 434eab898..fdf2ac644 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,9 @@ Unreleased
- Avoid crash in ``pserve --reload`` under Py3k, when iterating over posiibly
mutated ``sys.modules``.
+- ``UnencryptedCookieSessionFactoryConfig`` failed if the secret contained
+ higher order characters. See https://github.com/Pylons/pyramid/issues/1246
+
- Fixed a bug in ``UnencryptedCookieSessionFactoryConfig`` and
``SignedCookieSessionFactory`` where ``timeout=None`` would cause a new
session to always be created. Also in ``SignedCookieSessionFactory`` a
diff --git a/docs/quick_tutorial/hello_world.rst b/docs/quick_tutorial/hello_world.rst
index 86e1319f0..1a9ba4c9d 100644
--- a/docs/quick_tutorial/hello_world.rst
+++ b/docs/quick_tutorial/hello_world.rst
@@ -96,13 +96,13 @@ Extra Credit
.. code-block:: python
- print ('Starting up server on http://localhost:6547')
+ print('Incoming request')
...instead of:
.. code-block:: python
- print 'Starting up server on http://localhost:6547'
+ print 'Incoming request'
#. What happens if you return a string of HTML? A sequence of integers?
diff --git a/docs/quick_tutorial/hello_world/app.py b/docs/quick_tutorial/hello_world/app.py
index 210075023..0a95f9ad3 100644
--- a/docs/quick_tutorial/hello_world/app.py
+++ b/docs/quick_tutorial/hello_world/app.py
@@ -4,7 +4,7 @@ from pyramid.response import Response
def hello_world(request):
- print ('Incoming request')
+ print('Incoming request')
return Response('<body><h1>Hello World!</h1></body>')
@@ -14,4 +14,4 @@ if __name__ == '__main__':
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
- server.serve_forever() \ No newline at end of file
+ server.serve_forever()
diff --git a/pyramid/session.py b/pyramid/session.py
index 56d99e9de..a95c3f258 100644
--- a/pyramid/session.py
+++ b/pyramid/session.py
@@ -58,7 +58,12 @@ def signed_serialize(data, secret):
response.set_cookie('signed_cookie', cookieval)
"""
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
- sig = hmac.new(bytes_(secret), 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):
@@ -82,7 +87,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), 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)
diff --git a/pyramid/tests/test_session.py b/pyramid/tests/test_session.py
index 1aaa7a2ba..35c234e99 100644
--- a/pyramid/tests/test_session.py
+++ b/pyramid/tests/test_session.py
@@ -544,7 +544,7 @@ def serialize(data, secret):
from pyramid.compat import native_
from pyramid.compat import pickle
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
- sig = hmac.new(bytes_(secret), pickled, sha1).hexdigest()
+ sig = hmac.new(bytes_(secret, 'utf-8'), pickled, sha1).hexdigest()
return sig + native_(base64.b64encode(pickled))
class Test_signed_serialize(unittest.TestCase):
@@ -556,6 +556,18 @@ class Test_signed_serialize(unittest.TestCase):
expected = serialize('123', 'secret')
result = self._callFUT('123', 'secret')
self.assertEqual(result, expected)
+
+ def test_it_with_highorder_secret(self):
+ 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):
@@ -587,6 +599,19 @@ class Test_signed_deserialize(unittest.TestCase):
serialized = 'bad' + serialize('123', 'secret')
self.assertRaises(ValueError, self._callFUT, serialized, 'secret')
+ def test_it_with_highorder_secret(self):
+ 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