Closed yrro closed 5 months ago
Hi @yrro thanks for the issue. I'm a junior contributor here, but this seems like a no brainer for my eyes. I'll try to get this one through with the team.
Just for background, we're going through a bit of a drop in momentum. A few months ago we managed to get this repo over from somewhere unmaintained and still need to do a lot of work merging a previously popular fork. It's a pretty huge task.
Thanks for taking a look. I opened a pull request with the proposed change at https://github.com/pallets-eco/flask-session/pull/198 if that's helpful. With the Flask-Session quick start demo it gives the result:
$ curl -i localhost:5000/get/
HTTP/1.1 200 OK
Server: Werkzeug/3.0.1 Python/3.11.2
Date: Fri, 03 Nov 2023 12:29:11 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 7
Set-Cookie: session=FXRQglhzkeIFPon8Y80apw; Expires=Mon, 04 Dec 2023 12:29:11 GMT; HttpOnly; Path=/
Connection: close
not set
session
cookie value looks good to me.
Thanks again for the issue, updated in 0.6.0.
In reviews of a number of systems we have that use Flask-Session the way that session IDs are generated has been raised as an issue.
I'm asked for evidence that the session ID is generated with "sufficient randomness".
Here's what Flask-Session does:
https://github.com/pallets-eco/flask-session/blob/09094d30cfa1aace46f93a192260940bf95cf97b/src/flask_session/sessions.py#L62-L63
v4 UUIDs have 122 bits of randomness.
OWASP says "session identifiers should be at least 128 bits long to prevent brute-force session guessing attacks".
Does
uuid.uuid4()
use a cryptographically secure PRNG?In Python 3.11 it uses
os.urandom
which is documented to be "suitable for cryptographic use".Sufficient, but this explanation tends to generate a lot of paperwork and time spent reviewing my explanation.
Both of these points can be addressed by replacing the call to
uuid.uuid4()
with a call tosecrets.token_urlsafe(128//8)
, which returns a string in modified base64 encoding such as"u2sDdiy9v9ZdCrwb3-b3rb5m5o4C01JYgnS72biDcCA"
. This is 22 characters long, so we also save a bit of bandwidth by moving away from the 36-character long string representation of a UUID.