【问题标题】:Using Timestamps to Prevent Session Hijacking?使用时间戳来防止会话劫持?
【发布时间】:2011-06-17 05:16:36
【问题描述】:

我一直在寻找防止会话劫持的方法,即有人窃取会话 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 秒的缓冲区是否正确?我错过了哪些边缘情况?

【问题讨论】:

    标签: encryption security session-cookies session-hijacking


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 它不需要他们每 30 秒重新加载一次页面——他们可以离开任何时间。重要的是他们会话中的时间戳与下一次请求时存储在服务器上的时间戳相匹配。
    • 是的,任何未加密的数据都可能被拦截和复制,但除非他们从用户发出的最后一个请求中拦截会话,否则令牌/时间戳将在用户的下一个请求中更新,因此被拦截的令牌将无效。唯一有效的时间是他们能够在用户最后一次请求的 30 秒窗口内拦截并使用它。
    • 我想我不明白你的时间戳代表什么时间,你也在比较它。我刚刚重读了您的原始帖子,您说“每个会话的时间戳”。但是什么时候呢?它是什么时候创建的?您上次向用户发送页面是什么时候?等等。无论如何,你说这个时间戳会被发送回服务器。但随后任何嗅探线路的人都可以看到会话 ID 和时间戳。我看不出你得到了什么。无论如何,我认为你需要再澄清一下你在做什么。
    • 会话 cookie 由一个 user_id、session_id 和一个带有 SHA-1 签名的 AES 加密包中的时间戳组成。当用户登录时,会话被创建并且 cookie 被加上时间戳。当 Web 应用程序响应每个请求时,会话 cookie 会使用新的时间戳进行更新,并且服务器端数据存储也会使用相同的信息(user_id、session_id、时间戳)进行更新。
    • 所以页面加载后,用户浏览器中会有一个加密的会话cookie,时间戳为12345678,服务器也将记录存储的会话及其最后一个时间戳12345678。在下一个请求中,服务器将检查用户的会话 cookie 时间戳是否与存储在服务器上的会话时间戳匹配。
    猜你喜欢
    • 2012-08-27
    • 2012-05-19
    • 2012-02-20
    • 2017-12-22
    • 2010-11-28
    • 2020-07-15
    • 2012-04-17
    • 1970-01-01
    相关资源
    最近更新 更多