3

我一直在寻找防止会话劫持的方法,即有人窃取会话 cookie 并使用它来访问系统。

诸如http://codebutler.com/firesheep之类的程序可以很容易地嗅探开放无线网络上的会话,而其他获取会话的方式包括跨站点脚本攻击,或者只是将它们从受害者的计算机中取出。

使用 SSL 保护所有会话 cookie/服务器通信对于防止 Firesheep 嗅探至关重要,并且在 cookie 上设置 HTTPOnly 有助于防止 JavaScript 在 XSS 攻击中读取会话 cookie,但它仍然容易受到基于 AJAX 的攻击。

另一层是在每次请求时更新的会话 cookie 中包含安全令牌或随机数。您将令牌存储在服务器端数据存储区和 cookie 中,并在每个请求中比较 cookie 中的令牌与数据存储区中的令牌匹配。

如果令牌不匹配,则可能表明有人窃取了会话并试图使用它,因此您可以忽略请求或使会话无效并要求用户重新进行身份验证。但是,不匹配的令牌也可能是由于连接缓慢/不稳定造成的。

例如,您可能遇到这样的情况:服务器接收到来自真实用户的请求,更新服务器数据存储中的会话令牌,并使用包含更新令牌的会话 cookie 响应用户。但是由于连接缓慢/不稳定,用户没有收到响应,因此用户仍然拥有旧的会话令牌,而新的会话令牌存储在服务器上。当用户重试请求时,令牌将不匹配。

缓解此问题的一种方法是让服务器保留最后几个令牌的历史记录并检查它们是否匹配,但随后会变成要保留多少令牌的情况,具体取决于连接的脆弱程度或用户的点击满意度如何,服务器可能会在连接恢复之前循环浏览历史记录,并且浏览器会更新用户的会话。

保留令牌历史记录的另一种方法是为每个会话添加时间戳,并检查时间戳是否在某个短的指定范围内,例如 30 秒。如果用户的会话 cookie 时间戳在服务器存储的会话时间戳的 30 秒内,则认为该会话是真实的。

示例伪代码

def authenticate_request():

    if (stored_session.timestamp - session.timestamp > 30 seconds):
        return False
    return True

这避免了保留令牌历史记录——时间戳成为令牌——但攻击者在会话被盗后有 30 秒的机会劫持会话。虽然这是真的,但令牌历史替代方案并没有更好,因为它为攻击者提供了一个可能更长的机会窗口。

检查 IP 地址和用户代理更改的其他方法也存在问题。用户代理很容易被欺骗,如果攻击者能够获取用户的会话,他们可以通过相同的 XSS 代码或其他方式轻松确定用户代理。

如果用户在移动设备上,他们的 IP 地址可能会频繁更改,从而导致许多误报。此外,攻击者可能位于同一公司防火墙之后,因此用户和攻击者的 IP 与外部 Web 服务器相同。

使用时间戳令牌是正确的方法还是有更好的方法?30 秒的缓冲区是否正确?我错过了哪些边缘情况?

4

1 回答 1

2

我看不出时间戳是如何工作的。它要求用户在向服务器发送另一个请求之前,在页面上的停留时间不得超过 30 秒。我确定我花了超过 30 秒的时间阅读此页面并输入此回复,然后再按“发布”。

在我看来,存在一个固有问题,即您通过线路发送的任何数据都可能被拦截和复制。加密密码并不能解决问题,因为黑客可以拦截加密值,然后发送该加密值。他不一定关心未加密的值是什么。

您发送的任何令牌的故事都是一样的。黑客可以拦截令牌并复制它。

我听说的唯一似乎可以解决问题的想法是使用公钥和私钥的质询和响应系统:A 创建一个随机字符串,使用 B 的公钥对其进行加密,然后将其发送给 B。B 解密使用他的私钥的字符串,并将解密的值连同他的应用程序数据一起发回。然后 A 验证解密的值是否与原始值匹配。如果它不验证,他拒绝相关的数据。

如果黑客不知道 B 的私钥,他就无法截获来自 A 的消息并欺骗响应。黑客不能使用来自 B 的预先截获的回复,因为随机字符串每次都不同。

于 2011-06-16T21:16:36.860 回答