我刚刚从这个 atricle
http://shiflett.org/articles/session-fixation
学习会话固定攻击,
但是为了防御这种攻击,我不明白 session_regenerate_id() 的用途是什么?
当攻击者在 url 中包含会话 id 并向服务器说我想使用此会话时,与此会话相关的所有会话变量都对他而言,那么为什么重新生成 id 有用?
谢谢
3 回答
在网站的整个生命周期中,都会有许多“会话”。这些会话中的每一个都由一个 ID 标识,并且是网站如何知道谁是谁以及能够在不同请求之间保持状态的方式。
会话固定攻击只有在您能够获得会话 id 的情况下才真正可能发生。一些网站允许会话在不同的实际浏览会话之间持续存在(也称为“记住我”功能),如果使用相同的会话 ID,则更容易受到这种攻击。
如果我获得了您的会话 ID,那么只要该会话 ID 有效,我就可以冒充您。使用session_regenerate_id
,旧 ID 将失效,使其对任何可能截获它的人都无用。如果您在用户成功验证自己后生成一个新 ID,那么任何捕获会话标识符的尝试都将不再为经过身份验证的用户产生有效标识符(仅用户在验证自己之前拥有的“匿名”会话) ,这意味着攻击者只能“冒充”匿名用户。
一些更具安全意识的框架实际上会在浏览会话中重新生成会话 ID(使用低至 2-3 分钟的超时),而不是仅在用户登录时重新生成会话 ID,以帮助防止人们通过网络上的数据包嗅探获取会话 ID。会话 ID 只能在响应请求时重新生成。
要记住的关键点是,为了保持会话状态,客户端在每次请求时都会向服务器报告其当前会话 ID。报告机制本身(例如通过 cookie 或 URL 参数)在这里并不重要。
从服务器的角度来看,不包括正在采取的高级预防措施¹,客户端报告的会话 id 是权威的:服务器没有任何特定客户端的“正确”或“真实”会话 id 的概念。客户就是他们所说的那样。
当然,这提出了一个问题:那么是什么阻止我声明我是有权对您的应用程序执行任何操作的站点管理员?只有我不知道真正管理员的会话 ID 的事实(假设真正的管理员确实有一个会话)。如果我这样做了,我可以冒充管理员并做他们能做的任何事情。
所以现在从攻击者的角度来看:我怎样才能知道管理员的会话 ID?诱使管理员向服务器报告我自己选择的特定会话 ID 会奏效!这就是会话固定攻击的本质。
有几种方法可以防止或减轻这种攻击的影响,其中一种是让服务器告诉客户端“我更改了你的会话 ID;从现在开始,使用这个”。当然客户端不会被迫遵守,但友好的客户端当然会这样做(即使客户端是敌对的,服务器也可以拒绝识别客户端)。因此,即使攻击者设法欺骗管理员使用攻击者已知的特定会话 ID,只要服务器不指示客户端切换到不同的会话 ID,攻击就会起作用。
而这正是这样session_regenerate_id
做的。
¹ 高级预防措施:例如,服务器可能会跟踪客户端为每个会话 ID 使用的最后一个 IP 地址。如果服务器看到具有给定会话 id 的请求来自不同的 IP 地址,那么这可能被认为是可疑的。当然,这个简单的例子不能说明现代互联网基础设施的复杂性,但这个想法很清楚。高安全性服务(例如 Gmail)使用相同类型的复杂技术来检测和阻止可疑活动。
如果会话 ID 在 URL 中,并且攻击者以某种方式让另一个用户访问此 URL,则攻击者将知道会话 ID。
例如,假设攻击者将此代码段放在他们自己的网站“ evil.com
”上(为简洁起见,会话 ID 被修剪)
<a href="https://www.example.com/login.php?PHPSESSID=a123">Login to site to continue</a>
然后诱使他们的受害者访问他们的网站(例如向他们发送一封包含“ evil.com
”链接的电子邮件)。如果用户访问攻击者的网站,然后点击链接到“ example.com
”然后登录,攻击者可能会点击相同的链接并劫持现在登录的会话(因为 ID 将匹配)。例如,该链接可能指向 Facebook 上的一个有趣视频,但会在 URL 中包含会话 ID,而不仅仅是一个直接的登录页面。
然而,如果 session_regenerate_id() 作为登录过程的一部分被调用(在用户名和密码验证之后),会话 ID 现在将是新的,攻击者将无法使用此方法劫持会话。
这不是仅限于 URL 中的会话 ID 的漏洞。假设网站的其余部分是 HTTP,并且在登录后会话被移动到 HTTPS,那么重新生成会话 ID 也是明智的,因为当流量在 HTTP 上时,现有的会话 ID 可能已被拦截。