From 8db6c1b1e4b042435e40ea85e0bce4d45776630d Mon Sep 17 00:00:00 2001 From: Neil Schemenauer Date: Mon, 20 Nov 2017 13:37:55 -0800 Subject: [PATCH] If available, use 'secrets' module for randbytes(). --- quixote/util.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/quixote/util.py b/quixote/util.py index e15afec..03eb150 100644 --- a/quixote/util.py +++ b/quixote/util.py @@ -21,6 +21,10 @@ import mimetypes import urllib.request, urllib.parse, urllib.error import xmlrpc.client from email.utils import formatdate +try: + import secrets +except ImportError: + secrets = None import quixote from quixote import errors @@ -28,17 +32,19 @@ from quixote.directory import Directory from quixote.html import htmltext, TemplateIO from quixote.http_response import Stream -def _encode_base64(s): - return base64.urlsafe_b64encode(s).rstrip(b'=\n').decode('ascii') - -if hasattr(os, 'urandom'): +if secrets is not None: + # available in Python 3.6+, this is the preferred implementation + randbytes = secrets.token_urlsafe +elif hasattr(os, 'urandom'): # available in Python 2.4 and also works on win32 - def randbytes(n): + def _encode_base64(s): + return base64.urlsafe_b64encode(s).rstrip(b'=\n').decode('ascii') + def randbytes(n=16): """Return bytes of random data as a text string.""" return _encode_base64(os.urandom(n)) else: # give up, we used to try to provide a less secure version - def randbytes(n): + def randbytes(n=16): raise NotImplementedError('platform missing os.urandom') def import_object(name):