PHP会话固定/劫持

时间:2011-02-22 16:37:12

标签: php security session session-cookies

我正在尝试更多地了解PHP Session Fixation&劫持以及如何预防这些问题。我一直在阅读Chris Shiflett网站上的以下两篇文章:

但是,我不确定我是否理解正确的事情。

为了防止会话固定,调用session_regenerate_id(true)就足够了;成功登录某人后?我想我理解正确。

他还讨论了通过$ _GET使用在URL中传递的令牌来防止会话劫持。怎么会完全这样做?我猜测当有人登录时你会生成他们的令牌&将它存储在会话变量中,然后在每个页面上将该会话变量与$ _GET变量的值进行比较?

这个令牌只需要在每个会话或每个页面加载时更改一次吗?

他们是一个防止劫持而不必在网址中传递值的好方法吗?这将更容易。

5 个答案:

答案 0 :(得分:212)

答案 1 :(得分:37)

两个会话攻击都有相同的目标:获得对另一个用户的合法会话的访问权限。但是攻击媒介是不同的:

在两次攻击中,会话ID都是这些攻击所关注的敏感数据。因此,对于读访问(会话劫持)和写访问(会话修复),需要保护会话ID。

在这种情况下,使用HTTPS保护敏感数据的一般规则也适用。此外,您应该执行以下操作:

要防止会话修复攻击,请确保:

要防止会话劫持攻击,请确保:

要防止两次会话攻击,请确保:

  • 仅接受您的应用程序已启动的会话。您可以通过使用客户端特定信息对启动时的会话进行指纹识别来完成此操作。您可以使用 User-Agent ID,但不要使用远程IP地址或可能在请求之间更改的任何其他信息。
  • 在身份验证尝试后使用session_regenerate_id(true)更改会话ID(仅在成功时true)或更改权限并销毁旧会话。 (如果要保留与旧ID相关联的会话,请务必在重新生成ID之前使用$_SESSION 存储session_write_close的任何更改;否则只保留与新会话相关的会话ID将受这些更改的影响。)
  • 使用正确的会话到期实现(请参阅How do I expire a PHP session after 30 minutes?)。

答案 2 :(得分:6)

你提到的令牌是“nonce” - 一次使用的号码。它们不一定只能使用一次,但是它们使用的时间越长,可以捕获和用于劫持会话的几率就越高。

nonce的另一个缺点是很难构建一个使用它们的系统,并允许在同一个窗体上使用多个并行窗口。例如用户在论坛上打开两个窗口,并开始处理两个帖子:

window 'A' loads first and gets nonce 'P'
window 'B' loads second and gets nonce 'Q'

如果你无法跟踪多个窗口,你只能存储一个nonce - 窗口B / Q的那个。当用户然后从窗口A提交他们的帖子并传递nonce'P'时,系统将拒绝帖子为P != Q

答案 3 :(得分:2)

我没有阅读Shiflett的文章,但我认为你误解了一些东西。

默认情况下,只要客户端不接受cookie,PHP就会在URL中传递会话令牌。在最常见的情况下,会话令牌存储为cookie。

这意味着如果您在URL中放置会话令牌,PHP将识别它并尝试随后使用它。会话固定发生在有人创建会话然后通过打开包含会话令牌的URL欺骗其他用户共享同一会话时。如果用户以某种方式进行身份验证,则恶意用户会知道可能具有不同权限的经过身份验证的会话令牌。

正如我确信Shiflett解释的那样,通常要做的是每次用户权限更改时重新生成不同的令牌。

答案 4 :(得分:0)

是的,您可以通过在登录时重新生成会话ID来阻止会话固定。这样,如果攻击者不知道新认证会话的cookie值。另一种完全解决问题的方法是在运行时配置中设置session.use_only_cookies=True。攻击者无法在另一个域的上下文中设置cookie的值。会话固定依赖于将cookie值作为GET或POST发送。