所以我刚刚(我的一位用户)告诉我,我的登录信息不安全且会话很容易被劫持。
有人可以告诉我为什么以及如何纠正这个问题?
这是我的用户类:
class User
{
private $_db;
private $_isLogged;
public function __construct()
{
if (!session_id())
{
session_start();
}
$this->_db = Db::init();
$this->_checkLogin();
}
public function isLogged()
{
return $this->_isLogged;
}
public function login($username, $password)
{
$sth = $this->_db->prepare("SELECT * FROM users WHERE username = ?");
$sth->execute(array($username));
$result = $sth->fetch();
if ($result)
{
if ($result['password'] == md5($password))
{
$this->_setLogin($result);
return true;
}
}
return false;
}
public function logout()
{
session_destroy();
setcookie ("simpleLogin", "", time() - 3600, '/');
}
public function fbLogin($fbId)
{
$sth = $this->_db->prepare("SELECT * FROM users WHERE facebook = ?");
$sth->execute(array($fbId));
$result = $sth->fetch();
if ($result)
{
$this->_setLogin($result);
return true;
}
return false;
}
private function _setLogin($userData)
{
$_SESSION['logged'] = true;
$_SESSION['id'] = $userData['id'];
$_SESSION['username'] = $userData['username'];
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
try {
$sth = $this->_db->prepare("UPDATE users SET ip = ? WHERE id = ?");
$sth->execute(array($_SERVER['REMOTE_ADDR'], $userData['id']));
$forCookie = array(
'id' => $userData['id'],
'ip' => $_SERVER['REMOTE_ADDR'],
'username' => $_SESSION['username']
);
setcookie('simpleLogin', serialize($forCookie), time()+60*60*24*30, '/');
} catch (Exception $e) {
die('Database error: ' . $e->getMessage());
}
}
private function _checkLogin()
{
$this->_isLogged = false;
if (isset($_SESSION['logged']) && $_SESSION['logged'])
{
$sth = $this->_db->query("SELECT * FROM users WHERE id = " . $_SESSION['id']);
$result = $sth->fetch();
if ($result['ip'] == $_SESSION['ip'])
{
$this->_isLogged = true;
}
}
else if (isset($_COOKIE['simpleLogin']) && $_COOKIE['simpleLogin'])
{
$cookieData = unserialize(stripslashes($_COOKIE['simpleLogin']));
$sth = $this->_db->query("SELECT * FROM users WHERE id = " . $cookieData['id']);
$result = $sth->fetch();
if ($result['ip'] == $cookieData['ip'])
{
$this->_isLogged = true;
$this->_setLogin($result);
}
}
}
}
答案 0 :(得分:0)
通过更改此内容来摆脱SQL注入漏洞:
$sth = $this->_db->query("SELECT * FROM users WHERE id = " . $cookieData['id']);
......对此:
$sth = $this->_db->prepare("SELECT * FROM users WHERE id = :ident");
$sth->execute([':ident' => $cookieData['id']]);
这假设DB::init()
返回PDO
个实例。如果它是自定义类的实例,则需要在该类中实现参数绑定。