【发布时间】:2012-08-05 14:01:27
【问题描述】:
在检查 CodeIgniter 的会话处理机制时,我发现了一些我认为非常令人担忧的东西。
$expire = $this->now - $this->sess_expiration;
$this->CI->db->where("last_activity < {$expire}");
$this->CI->db->delete($this->sess_table_name);
看来 CI 实际上是根据 last_activity 而不是一个固定的、不可变的过期字段来确定会话过期时间的。
这里的问题是,只要会话更新,last_activity 就会更新为 now()。因此,假设您使用 CI 默认设置,并且会话持续 7200 秒(2 小时),每 300 秒(5 分钟)更新一次
会话在最后一次更新的 5 分钟后被标记为需要更新,因此如果用户在这 5 分钟之后但在 2 小时之前提交了他的会话 cookie,那么 CI 会将会话延长到从这个时间再持续 2 小时时刻,因为 last_activity 将更新为 now()。
这对我来说似乎是一个巨大的安全风险,因为只要用户处于活动状态并不断触发会话更新,其持续时间就会无限期延长,有效地使过期设置无用。我通过将更新设置为 10 秒并将到期时间设置为 20 对此进行了测试。我可以确认,只要我每 10 秒刷新一次,会话就永远不会过期!
想象一下,如果攻击者窃取了您的登录 cookie 并建立了有效会话。即使您使登录 cookie 无效,攻击者也可以无限期地保持其会话有效,只要他经常提交 cookie 即可。
你怎么看?我在这里错过了一些重要的事情吗?或者这真的像看起来那样糟糕吗?
【问题讨论】:
-
我认为网站通常是这样工作的。如果您希望会话在登录后两小时到期,即使它在该会话期间一直在正常使用,那么 (a) 这是一个异常高的安全要求,并且 (b) 您可能需要自己的会话处理程序。
-
这不是安全漏洞。这就是 PHP 会话默认的工作方式,在决定是否过期之前查看会话文件的修改时间。
-
会话超时用于使 inactive 会话过期。您不希望您的客户必须每两个小时重新登录一次,因为这很烦人,并且可能会破坏他们在登录后两个小时后在您的网站上所做的任何事情。
-
嗯,这可以解释一些事情。出于某种原因,我从未在任何地方遇到过这些信息。谢谢大家的意见。
-
关于“如果您使登录 cookie 无效”。获取会话(可能包含 member_id)后,您可以/应该检查用户凭据是否仍然有效,如果没有则销毁会话。
标签: php security codeigniter session