根据the Django documentation,签名的cookie会话存储很容易受到重放攻击:
还请注意,尽管MAC可以保证 数据(它是由您的网站而非其他人生成的),并且 数据的完整性(所有数据都正确无误), 无法保证新鲜度,即您将被送回最后 你发送给客户的东西。这意味着对于会话的某些用途 数据,Cookie后端可能会让您重播攻击。不像 其他会话后端,这些后端保留每个会话的服务器端记录 并在用户注销时使其无效,但基于cookie的会话不会 用户注销时无效。因此,如果攻击者窃取了用户的 Cookie,他们可以使用该Cookie以该用户身份登录,即使 用户注销。 Cookies只会被检测为“陈旧” 比您的SESSION_COOKIE_AGE大。
这是否意味着:
SESSION_COOKIE_AGE
相比,并明确拒绝它认为过时的数据。从技术上讲,Django可以在不持久化数据服务器端的情况下确定会话的“旧”程度,但是文档似乎不清楚这是否在做,还是Django依赖/信任用户的浏览器杀死旧的Cookie(因此,如果数据在过期之前被捕获,则会话仍可以重播)。
答案 0 :(得分:3)
Django通过SessionMiddleware
将HTTP cookie expiration设置为SESSION_COOKIE_AGE
。这告诉浏览器何时应将cookie视为“太旧”并过期。这很好另外,如果浏览器检测到不应再使用Cookie,则它将不再使用它,从而使Django不必花费时间检查仍然无法使用Cookie的时间。
但是, Django不依赖浏览器来确保不再使用过期的Cookie 。流氓代理可以获取Cookie的副本,然后在其过期日期之后重新使用它。 Django通过将Cookie发送到以下格式的浏览器来防止这种情况:
<payload>:<creation stamp>:<signature>
冒号是按字面意义出现在数据中的分隔符。 <payload>
是实际的会话数据。 <creation stamp>
是创建cookie时添加的时间戳,<signature>
是用于标记有效负载和创建戳记的MAC签名。
您可以在django.core.signing
中查看相关代码。文件顶部的注释为您提供了使用Signer
类的基本签名方案。此类不了解时间戳。但是,在签署cookie时,Django使用TimestampSigner
,它确实了解时间戳并生成上面显示的格式。
当TimestampSigner
unsigns一个cookie时,它将检查时间戳记,如果它太旧则引发异常:
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
答案 1 :(得分:-2)
长话短说,您需要设置一个简短的SESSION_COOKIE_AGE
,以确保恶意用户不会利用您的网站。
这可能实现如下:
SESSION_COOKIE_AGE
进行比较。SESSION_COOKIE_AGE
,它将拒绝请求