使用时间戳来防止会话劫持?

时间:2011-06-16 20:36:39

标签: encryption security session-cookies session-hijacking

我一直在寻找防止会话劫持的方法,其中有人窃取会话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秒的缓冲区是对的吗?我遗漏了哪些边缘案例?

1 个答案:

答案 0 :(得分:2)

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

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

您发送的任何令牌的相同故事。黑客可以拦截令牌并复制它。

我听到的唯一一个解决问题的想法是使用公钥和私钥的挑战 - 响应系统:A创建一个随机字符串,使用B的公钥对其进行加密,并将其发送给B. B使用其私钥解密该字符串,并将解密后的值与其应用程序数据一起发回。然后,A验证解密的值是否与原始值匹配。如果它没有验证,他拒绝相关数据。

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