我继承了一个旧的基于PHP的网站,一直被黑客入侵。根据我在此处找到的信息:How can I prevent SQL injection in PHP?, 我使用PDO参数化查询更新了sql查询。我们上周再次遭到黑客入侵,看起来像是一次sql注入攻击 所有用户名都从用户表中删除,并替换为他们自己的信息。然后黑客能够进入管理部分 网站并制造各种各样的破坏。
参数化查询怎么会发生这种情况?
请参阅下面的代码 - 我错过了什么?我要更改用于此查询的db登录的权限,以便只允许选择,但我真的想知道为什么 该查询易受攻击。
class pdoConnection
{
var $conn;
function pdoConnection()
{
$this->createConnection();
}
function createConnection()
{
try
{
$dbConnection = new PDO('mysql:host=mysqlhostname.com;dbname=mydbname;charset=utf8',
'dbusername', 'dbpassword',
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbConnection -> exec('SET NAMES utf8');
$dbConnection -> exec('SET CHARACTER SET utf8');
$this->conn =$dbConnection;
}
catch(PDOException $e)
{
die('Could not connect: ' .$e->getMessage(). "<br><br>");
}
}
// GET CONNECTION
// ---------------------------------------------------------------------
function getConnection()
{
return $this->conn;
}
}
$login = htmlspecialchars($_REQUEST['login'], ENT_QUOTES, 'UTF-8');
$pass = htmlspecialchars($_REQUEST['pass'], ENT_QUOTES, 'UTF-8');
$msg = '';
//check to see if there is a value
if($login == '' || $pass == '') {
$error = 1;
$msg = "Please enter a username and password.<br />";
}
else
{
//try to validate
$clsPDO = new pdoConnection();
$con = $clsPDO->getConnection();
$stmt = $con->prepare('SELECT * FROM users where userName = :login');
$stmt->execute(array(':login' => $login)) or die($con->errorInfo());
$row = $stmt->fetch();
if (isset($row))
{
if( $pass == $row['userPassword']) {
$required_login = $row['userName'];
$required_pass = $row['userPassword'];
$userLevel = $row['userLevelID'];
$userName = $row['userName'];
$userID = $row['userID'];
}
else
{
$error = 1;
$msg = "Your username/password did not match. Please check your entries and try again.";
}
}
else
{
//did not validate
$error = 1;
$msg = "Your username/password did not match. Please check your entries and try again.";
}
}
答案 0 :(得分:2)
我最近调查过有关此主题的几个讨论和教程,我在代码中看不到任何安全漏洞。您正在关闭仿真,将字符集设置为已知安全字符集,并正确使用预准备语句。那就说了两点:
您可以确认数据库服务器上正在使用真正的预准备语句,而不是由PDO模拟。你告诉它你想要什么,但这与确认它发生的情况并不完全相同。同样适用于字符集配置。您多次尝试正确设置它表明您不相信系统会听取您的意见。从我读到的关于该功能的历史的内容来看,这是可以理解的。
即使有人发现您发布的代码中存在漏洞,但这似乎也不足以让人相信它在这种情况下被利用了。也没有人指出漏洞意味着代码是安全的。因此,安全似乎在于进一步取证,增加“下一次”的记录,以及考虑替代攻击媒介。