会话和请求中继器的Flask安全问题



我使用的是Flask内置会话机制。

以下是我对会话机制(带烧瓶)的理解:

  • 所有会话数据都存储在签名的cookie中(带有app.secret_key)
  • 当会话数据被修改时,cookie会被更改
  • 会话的数据受到写客户端保护(由于签名),但不受读取保护

想象一下以下场景:

  • 在我的会话中,我放置了一个变量try_number=3
  • 每次用户执行操作时,都会减少此数字
  • 如果此数字等于0,则禁止操作

用户第一次连接到应用程序,应用程序发送一个Set-Cookie: sesssion=Flask.sign("try_number=3"),让我们将此cookie称为COOKIE_A

用户执行他的第一个操作,他发送COOKIE_A,应用程序用Set-Cookie: sesssion=Flask.sign("try_number=2")回复,让我们把这个COOKIE称为COOKIE_B

现在,如果用户执行了另一个操作,但没有再次使用COOKIE_B而是使用COOKIE_A(例如使用curl),则cookie仍然是签名的,并且将由服务器使用try_number=3来处理。

因此,只有使用COOKIE_A进行所有操作,他才能"欺骗"会话机制,并在同一会话中进行无限制的操作。

有什么内在机制可以防止这种情况发生吗?(我说的不是使用sqlite/redis的代码片段,而是内置解决方案)

这不是Flask cookie安全性的失败,而是计数器设计的失败。没有针对重播攻击的内置保护。

您可以缩短会话cookie的过期时间。这并不能真正解决问题,只会使窗口变小。它还使会话不便于正常使用,这会惹恼您的普通用户。

最终,你必须在服务器上存储一些信息并进行检查。你可以在每个请求中发送一个nonce,并保存已发送回的信息,忽略以前看到的信息。您还可以将所有会话信息(除了一些标识密钥)存储在服务器端,这样就无法重新发送。

最新更新