[pyramid/security] use cryptographically secure random generator
Based on django source code in case SystemRandom is not available.
According to python documentation:
https://docs.python.org/2/library/random.html
> Warning
> The pseudo-random generators of this module should not be used for security
> purposes. Use os.urandom() or SystemRandom if you require a cryptographically
> secure pseudo-random number generator.
--- a/cubicweb/pyramid/config.py Thu Mar 14 16:17:49 2019 +0100
+++ b/cubicweb/pyramid/config.py Tue Feb 12 17:00:55 2019 +0100
@@ -18,6 +18,8 @@
"""Configuration for CubicWeb instances on top of a Pyramid application"""
from os import path
+import hashlib
+import time
import random
import string
@@ -32,7 +34,9 @@
def get_random_secret_key():
"""Return 50-character secret string"""
chars = string.ascii_letters + string.digits
- return "".join([random.choice(chars) for i in range(50)])
+ secure_random = random.SystemRandom()
+
+ return "".join([secure_random.choice(chars) for i in range(50)])
class CubicWebPyramidConfiguration(BaseWebConfiguration, ServerConfiguration):
--- a/cubicweb/pyramid/test/test_config.py Thu Mar 14 16:17:49 2019 +0100
+++ b/cubicweb/pyramid/test/test_config.py Tue Feb 12 17:00:55 2019 +0100
@@ -31,7 +31,7 @@
class PyramidConfigTC(TestCase):
def test_get_random_secret_key(self):
- with patch('random.choice', return_value='0') as patched_choice:
+ with patch('random.SystemRandom.choice', return_value='0') as patched_choice:
secret = config.get_random_secret_key()
self.assertEqual(patched_choice.call_count, 50)
self.assertEqual(secret, '0' * 50)
@@ -43,7 +43,7 @@
os.environ['CW_INSTANCES_DIR'] = instancedir
try:
cfg = config.CubicWebPyramidConfiguration(appid)
- with patch('random.choice', return_value='0') as patched_choice:
+ with patch('random.SystemRandom.choice', return_value='0') as patched_choice:
cfg.write_development_ini(['foo', 'bar'])
finally:
os.environ.pop('CW_INSTANCES_DIR')