防止会话劫持

2022-08-30 08:36:11

如何防止多个客户端使用相同的会话 ID?我问这个是因为我想添加一个额外的安全层,以防止我的网站上的会话劫持。如果黑客以某种方式找出了另一个用户的会话ID并使用该SID发出请求,我如何检测到服务器上共享单个SID的不同客户端,然后拒绝劫持尝试?

编辑

经过仔细考虑,我接受了Gumbo的答案,因为我已经意识到,由于无状态HTTP协议的限制,我所要求的是不可能的。我忘记了HTTP最基本的原则是什么,现在我想到这个问题似乎有点微不足道。

让我详细说明我的意思:

用户 A 登录 example.com 后,他会获得一些随机的会话 ID,为简单起见,让它成为 'abc123'。此会话 ID 作为 Cookie 存储在客户端,并使用服务器端会话进行验证,以确保登录的用户在从一个网页移动到另一个网页时保持登录状态。当然,如果HTTP不是无状态的,则此cookie不需要存在。因此,如果用户 B 窃取了用户 A 的 SID,并在他的计算机上创建了一个值为“abc123”的 Cookie,他将成功劫持用户 A 的会话,但服务器根本无法合法地识别用户 B 的请求与用户 A 的请求有任何不同,因此服务器没有理由拒绝任何请求。即使我们列出了服务器上已经处于活动状态的会话,并尝试查看是否有人正在访问已处于活动状态的会话,我们又如何确定是另一个非法访问会话的用户,而不是已经使用会话ID登录的同一用户, 但只是尝试用它提出另一个请求(即导航到不同的网页)。我们不能。正在检查用户代理?可以欺骗 - 但作为纵深防御措施仍然很好。IP地址?可以出于合法原因进行更改 - 但我建议检查IP的前两个八位字节,而不是根本不检查IP地址,因为即使是数据计划网络上的用户,由于完全合法的原因不断更改IP,通常也只有IP更改的最后两个八位字节。

总而言之,无状态HTTP使我们永远无法完全保护我们的网站免受会话劫持,但是良好的做法(如Gumbo提供的做法)足以防止绝大多数会话攻击。因此,试图通过拒绝同一 SID 的多个请求来保护会话免遭劫持简直是荒谬的,并且会破坏会话的整个目的。


答案 1

不幸的是,没有有效的方法来明确地识别来自攻击者的请求,而不是真正的请求。因为大多数反测量检查的属性,如IP地址或用户代理特征,要么不可靠(IP地址可能在多个请求之间更改),要么很容易伪造(例如,用户代理请求标头),因此会产生不需要的误报(即真正的用户交换IP地址)或假阴性(即攻击者能够成功地使用相同的用户代理伪造请求)。

这就是为什么防止会话劫持的最佳方法是确保攻击者无法找到其他用户的会话ID。这意味着您应该设计应用程序及其会话管理:(1)攻击者无法通过使用足够的熵来猜测有效的会话ID,并且(2)攻击者没有其他方法可以通过已知的攻击/漏洞(例如嗅探网络通信,跨站点脚本,通过 Referer 泄漏)获得有效的会话 ID, 等。

也就是说,您应该:

除此之外,在某些会话状态更改(例如,登录后确认真实性或更改授权/权限)后,您还应该重新生成会话ID,同时使旧会话ID无效(请参阅session_regenerate_id功能),并且您还可以定期执行此操作以减少成功会话劫持攻击的时间跨度。


答案 2

我们能做这样的事情吗?

将会话 ID 存储在数据库中。还要存储该会话 ID 的 IP 地址和HTTP_USER_AGENT。现在,当请求到达包含该匹配会话ID的服务器时,请检查它来自脚本中的哪个代理和ip。

可以通过为会话创建公共函数或类来使此基础工作,以便在处理每个请求之前对其进行验证。这几乎不需要几微秒。但是,如果许多用户正在访问您的网站,并且您拥有庞大的会话数据库,那么这可能是一个小的性能问题。但是,与其他方法(如=>使用重新生成会话)相比,它肯定会非常安全。

在重新生成会话 ID 时,会话劫持的可能性也很小。

假设用户的会话 ID 被复制,并且该用户在一段时间内不工作或处于活动状态,并且没有向具有旧会话 ID 的服务器发出请求以请求重新生成新会话 ID。然后,如果会话ID被劫持,黑客将使用该会话ID并使用该ID向服务器发出请求,然后服务器将使用重新生成的会话ID进行响应,以便黑客可以继续使用服务。实际用户将无法再操作,因为他不知道重新生成的 ID 是什么,以及要在请求中传递什么请求会话 ID。完全消失了。

如果我在某处错了,请纠正我。


推荐