最近有一名黑客试图使用睡眠注射减慢我的网站速度。虽然我们正在使用mysql_real_escape_string()
等预防措施来覆盖大多数易受攻击的输入。我们通过查询字符串传递产品的id,并将命令设为:
$id = mysql_real_escape_string($_REQUEST['id']);
$qry = "Select * from products where id = ".$id;
但是黑客试图提供输入
?id=3 and sleep(4)
并且查询变为
Select * from products where id = 3 and sleep(4);
虽然有一些可能的解决方案,如
还有其他方法可以阻止这种情况吗?什么是预防睡眠注射的最佳方法?
答案 0 :(得分:20)
你没有正确逃脱。 mysql_real_escape_string
用于正确转义SQL string 语法,但您只是将值嵌入为裸值,而不是SQL字符串。你需要:
$qry = "SELECT * FROM products WHERE id = '$id'";
请注意查询中id周围的引号。
如果id是数字,则转换为数字会更明智:
$id = (int)$_GET['id'];
答案 1 :(得分:10)
防止SQL注入的最佳方法是使用当前技术。不推荐使用MySQL mysql_
系列函数,将在以后的版本中从PHP中删除。
您应该使用MySQLi或PDO的预准备语句。
这些技术使用预准备语句和参数化查询。 SQL语句由数据库服务器与任何参数分开解析。攻击者无法注入恶意SQL。
你基本上有两个选择来实现这个目标:
$stmt = $dbConnection->prepare('SELECT * FROM table WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
PDO:
$stmt = $pdo->prepare('SELECT * FROM table WHERE name = :name');
$stmt->execute(array(':name' => $name));
foreach ($stmt as $row) {
// do something with $row
}
您传递给prepare
的SQL语句会被数据库服务器解析和编译。通过指定参数(?
或命名参数,如:name
),您可以告诉数据库引擎要过滤的内容。然后,当您调用execute
时,预准备语句将与您指定的参数值组合。
这里重要的是参数值与编译语句结合,而不是SQL字符串。 SQL注入通过在创建SQL以发送到数据库时欺骗脚本来包含恶意字符串。因此,通过从参数中单独发送实际SQL,可以限制结束您不想要的内容的风险。使用预准备语句时发送的任何参数都将被视为字符串(尽管数据库引擎可能会进行一些优化,因此参数最终也可能作为数字)。
答案 2 :(得分:2)
这是一个错误的问题。
“如何防止mysql注入?”必须如此。睡觉或不睡觉 - 没关系。
此问题已经很多的答案
答案 3 :(得分:0)
您应该使用PDO或mysqli将查询转换为“预备语句”。