在从php会话注销期间取消设置cookie有什么意义?

我正在使用PHP开发一个Web应用程序,用户可以拥有自己的帐户,跟踪用户的会话存储在MySQL数据库中.现在,在搜索了如何实现这个的答案后,我发现很多人都喜欢使用session_destroy()并取消设置cookie.为什么 – session_destroy()本身不够用吗?甚至the PHP manual说“为了完全杀死会话,比如要将用户注销,会话ID也必须取消设置.”

我的理由:在用户退出之后,并且在离开之前恰好访问了您网站上的另一个页面,检查用户是否登录的PHP脚本将调用session_start(),为用户设置新的会话cookie无论如何.这是它的样子:

// here we include some scripts and make some instances we'll need
require_once("database.php");
require_once("session.php");
$database_connection = new DB_Connection();
$session = new Session($database_connection);

// here a session cookie is sent to a user, even if he or she isn't logged in
session_start();

// finally we check if the user is logged in
$log_isLogged = false;
if(isset($_SESSION['member_id'], $_SESSION['username'])){
    $log_member_id = $_SESSION['member_id'];
    $log_username = $_SESSION['username'];
    $log_isLogged = true;
}

当然,当用户知道这个事实并且在可能设置新cookie之前离开网站时,这很好.但有些网站甚至会在注销后直接将您重定向到新页面,从而产生新的会话cookie – 撤消您刚才所做的事情.

我的推理在某种程度上是有缺陷的,或者如果你取消会话cookie不是真的重要吗?
也许大多数开发人员只是认为它至少不会伤害它来解决它?

我不是母语人士,所以我提前为任何拼写错误和语法错误道歉.

解决方法:

(命名不佳)session_destroy()功能仅删除会话中的数据.它不会从浏览器中删除会话cookie,并使session_id与会话相关联. session_start()仅向客户端发出新的session_id,如果客户端的请求中尚未提供.您的代码很容易受到称为session fixation的攻击,其中恶意攻击者将在您的站点上启动会话以获取有效的session_id,然后欺骗您网站的不知情用户使用攻击者已知的session_id登录.这可以通过向受害者发送带有URL中的session_id的链接(如果您的站点将以这种方式接受)或其他各种方法来实现.一旦受害者登录,攻击者就会以同一个用户的身份有效登录.

为了防止会话固定攻击,您应该:

>成功登录后,通过拨打session_regenerate_id()向客户端发出全新的session_id.
>注销时,完全销毁服务器和客户端上会话的每个工件.这意味着调用session_destroy()并使用setcookie()取消设置客户端cookie.
>确保您的站点不会在URL中公开session_id或接受URL中提供的session_id.
>确保你的session_ids足够长且随意,以至于它们几乎不会被攻击者猜到.
>确保您的站点不容易受到cross site scripting攻击,这将允许攻击者从已登录的用户窃取有效的session_id.
>确保您的登录通过https进行,会话cookie标记为安全.与会话相关的所有通信都应通过https进行.永远不能通过http发送客户端的session_id,因为这会在传输过程中暴露它.

进一步参考:OWASP Top Ten page on session management

上一篇:php unset()函数


下一篇:php 魔术变量 __unset()