As per the Django documentation, signed cookie session storage is vulnerable to a replay attack:
Note also that while the MAC can guarantee the authenticity of the data (that it was generated by your site, and not someone else), and the integrity of the data (that it is all there and correct), it cannot guarantee freshness i.e. that you are being sent back the last thing you sent to the client. This means that for some uses of session data, the cookie backend might open you up to replay attacks. Unlike other session backends which keep a server-side record of each session and invalidate it when a user logs out, cookie-based sessions are not invalidated when a user logs out. Thus if an attacker steals a user’s cookie, they can use that cookie to login as that user even if the user logs out. Cookies will only be detected as ‘stale’ if they are older than your SESSION_COOKIE_AGE.
Does this mean that:
SESSION_COOKIE_AGE
and explicitly rejects data it deems as stale.It seems technically possible for Django to be able to determine how 'old' a session is without persisting this data server-side, but the docs don't seem clear about whether or not this is being done, or is Django relying on / trusting the user's browser to kill old cookies (and thus the session could still be replayed if the data was captured prior to its expiry).
This means that for some uses of session data, the cookie backend might open you up to replay attacks. Unlike other session backends which keep a server-side record of each session and invalidate it when a user logs out, cookie-based sessions are not invalidated when a user logs out.
Using database-backed sessions If you want to use a database-backed session, you need to add 'django. contrib. sessions' to your INSTALLED_APPS setting. Once you have configured your installation, run manage.py migrate to install the single database table that stores session data.
Django uses a cookie containing a special session id to identify each browser and its associated session with the site. The actual session data is stored in the site database by default (this is more secure than storing the data in a cookie, where they are more vulnerable to malicious users).
Django, through SessionMiddleware
, does set the HTTP cookie expiration to SESSION_COOKIE_AGE
. This tells the browser when the cookie should be considered "too old" and expired. This is good housekeeping. Also, if the browser detects that a cookie should not be used anymore, it won't use it and this saves Django from spending time examining a cookie can't be used anyway.
However, Django does not rely on the browsers to ensure that expired cookies cannot ever be used again. A rogue agent could get a copy of the cookie and then reuse it past its expiration date. Django prevents this by sending the cookie to the browser formatted like this:
<payload>:<creation stamp>:<signature>
The colons are separators appearing literally in the data. <payload>
is the actual session data. <creation stamp>
is a time stamp added when the cookie is created, and <signature>
is the MAC signature that signs the payload and the creation stamp.
You can see the relevant code in django.core.signing
. The comments at the top of the file give you the basic signing scenarios using the Signer
class. This class does not know about timestamps. However, when signing cookies, Django uses TimestampSigner
, which does know about timestamps and produces the format I've shown above.
When TimestampSigner
unsigns a cookie, it checks the timestamp and raises an exception if it is too old:
def unsign(self, value, max_age=None):
"""
Retrieve original value and check it wasn't signed more
than max_age seconds ago.
"""
result = super().unsign(value)
value, timestamp = result.rsplit(self.sep, 1)
timestamp = baseconv.base62.decode(timestamp)
if max_age is not None:
if isinstance(max_age, datetime.timedelta):
max_age = max_age.total_seconds()
# Check timestamp is not older than max_age
age = time.time() - timestamp
if age > max_age:
raise SignatureExpired(
'Signature age %s > %s seconds' % (age, max_age))
return value
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With