3

This question is inspired by looking at the functionality of the Flask-Login extension for the Python's Flask Framework (Web Framework).

This extension generates a session identifier using the user's ID and storing it in Flask's Session, a signed cookie (meaning the contents are visible)[source]:

It will:

  • Store the active user’s ID in the Flask Session, and let you easily log them in and out.

However, I have seen many sources, such as OWASP [source], recommending a CSPRNG (Cryptographically Secure Pseudorandom Number Generator) approach for generating the session identifier. We also need to take into account that Flask-Login's approach also disclosures information to a malicious attacker (user id).

Although there is a session protection feature, which implements an identifier based on the IP and user-agent (which could also be forged), this question is about the level of security of the Session ID alone.

Compared to the OWASP full-random session identifier, is this approach strong enough to be considered "secure"? From what attacks could it suffer which the OWASP approach avoids?

Also, could signing a randomly generated session ID provide any significant benefits?

1
  • Flask actually allows custom session providers, which means you could hypothetically change the signed cookies for random identifiers which are later used in the database for getting the user. However, this wasn't pointed out in Flask-Login docs.
    – WhiteFox
    Jul 4, 2023 at 21:46

1 Answer 1

2

Signed cookies are generally a valid alternative to server-side sessions which are referenced with a random ID. The benefit is that all session data can be stored by the client and doesn't have to be managed by the server.

However, there are three major downsides when it comes to security.

  • The secret key used for “signing” the cookies (the “signature” is usually a message authentication code) becomes a single point of failure. If it ever gets leaked, the entire session security breaks down, because anybody who has the key can freely choose the session content and therefore log in as an arbitrary user.
  • Invaliding sessions is tricky. If you simply hand out a signed user ID as a cookie, then this session is, in principle, valid forever. Even if you try to overwrite the cookie (e.g., as part of the log-out procedure), nothing prevents the client from restoring the old cookie and sending it to the server. The only way to definitely end the session is to change the user ID -- which isn't a particularly elegant solution. Additionally, you can (and should) store a signed timestamp together with the user ID to invalidate the session after a certain time.
  • Signed cookies are technically much more complex than database lookups, so the chance of making a mistake which affects security is bigger.

So overall, server-side sessions which are referenced with a random ID are more robust and the preferred solution. Signed cookies can be secure as well, but they require extra work.

As to your last question: No, signing random session IDs doesn't provide any benefit. The whole point of randomizing the IDs is that they cannot be guessed, so there's no need to prevent them from being changed.

2
  • The second statement is definitely a weakness. If you look thoroughly through the Flask-Login documentation, it suggests creating an alternative unique ID for each user, in order to be able to invalidate sessions, which only adds to complexity.
    – WhiteFox
    Jul 4, 2023 at 16:37
  • 1
    Correct. And since those alternative user IDs have to be stored server-side, this largely defeats the sole benefit of signed cookies (all session data is stored by the client). At this point, you might as well implement classical server-side sessions.
    – Ja1024
    Jul 4, 2023 at 19:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .