我一直在研究我的网站(PHP)的安全性,并且有很多信息需要摄取。我试图实现我在OWASP上研究过的安全性,但有一件事我有点紧张,除其他外,还有当用户注销时如何处理SESSIONS。
目前我正在使用的是:
session_destroy();
但是,我已经读过我应该更改XRSF令牌并启动另一个SESSION,这样它就会强制用户重新提交登录凭据,反过来明确地结束用户SESSION。
session_destroy()
是否足够?
修改
我已经下载了michael-the-messenger,我认为这是由Michael Brooks(Rook)创建的,这应该是非常安全的,我看到了一些我可能想要使用的代码。这是否可以安全地替换我正在使用的session_destroy()
?
CODE
if($_SESSION['user']->isAuth())
{
/* if they have clicked log out */
/* this will kill the session */
if($_POST['LogMeOut'] == 'true')
{
//When the user logs out the xsrf token changes.
$tmp_xsrf = $_SESSION['user']->getXsrfToken();
$_SESSION['user']->logout();
$loginMessage = str_replace($tmp_xsrf, $_SESSION['user']->getXsrfToken(), $loginMessage);
print layout('Authorization Required', $loginMessage);
}
else
{
header("Location: inbox.php");
//user is allowed access.
}
}
else
{
// code goes on ....
LOGOUT
public function logout()
{
$_SESSION['user'] = new auth();
}
显然$_SESSION['user'] = new auth();
重新实现了将私有变量$auth
设置为false的对象。
答案 0 :(得分:2)
但有一点我有点紧张,除其他外,是如何 在用户注销时处理SESSIONS。
根据manual:
为了完全杀死会话,喜欢将用户注销掉, 会话ID也必须取消设置。如果使用cookie来传播 会话ID(默认行为),然后会话cookie必须是 删除。 setcookie()可以用于此。
因此,为了安全地销毁会话,我们也会在客户机上擦除它。
session_destroy()
以及setcookie(session_name(), null, time() - 86400)
将会这样做。
除此之外,
会话存储仅在内部使用数据序列化。通过存储 你刚才做的
$_SESSION
超全球中的一个对象 在不知道的情况下按需序列化/反序列化该对象。
1)通过在$_SESSION
中存储对象,您确实引入了全局状态。 $_SESSION
是一个超全局数组,因此可以从任何地方访问。
2)即使存储保存有关已登录用户信息的对象,也会浪费系统内存。对象表示的长度总是大于字符串的长度。
但是为什么你甚至应该关心包装会话功能呢?那么,
$_SESSION['foo']
,而是$session->read['foo']
如果将所有与会话相关的功能包装到一个signle类中,那么它将变成有吸引力的:
$session = new SessionStorage();
$session->write( array('foo' => 'bar') );
if ( $session->isValid() === TRUE ) {
echo $session->read('foo'); // bar
} else {
// Session hijack. Handle here
}
// To totally destroy a session:
$session->destroy();
// if some part of your application requires a session, then just inject an instance of `SessionStorage`
// like this:
$user = new Profile($session);
// Take this implementation as example:
final class SessionStorage
{
public function __construct()
{
// Don't start again if session is started:
if ( session_id() != '' ) {
session_start();
}
// Keep initial values
$_SESSION['HTTP_USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
}
/**
* You can prevent majority of hijacks using this method
*
* @return boolean TRUE if session is valid
*/
public function isValid()
{
return $_SESSION['HTTP_USER_AGENT'] === $_SERVER['HTTP_USER_AGENT'] && $_SESSION['REMOTE_ADDR'] === $_SERVER['REMOTE_ADDR'] ;
}
public function __destruct()
{
session_write_close();
}
/**
* Fixed session_destroy()
*
* @return boolean
*/
public function destroy()
{
// Erase the session name on client side
setcookie(session_name(), null, time() - 86400);
// Erase on the server
return session_destroy();
}
public function write(array $data)
{
foreach($data as $key => $value) {
$_SESSION[$key] = $value;
}
}
public function exists()
{
foreach(func_get_args() as $arg){
if ( ! array_key_exists($arg, $_SESSION) ){
return false;
}
}
return true;
}
public function read($key)
{
if ( $this->exists($key) ){
return $_SESSION[$key];
} else {
throw new RuntimeException('Cannot access non-existing var ' .$key);
}
}
}
答案 1 :(得分:-2)
也许你正在寻找session_unset()。