如何在PHP中阻止SQL注入?
使用预准备语句和参数化查询。这些是由数据库服务器与任何参数分开发送和解析的SQL语句。这样攻击者就无法注入恶意SQL。
你基本上有两个选择来实现这个目标:
使用PDO(适用于任何支持的数据库驱动程序):
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));
foreach ($stmt as $row) {
// do something with $row
}
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name); // 's' specifies the variable type => 'string'
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
如果您要连接到MySQL以外的数据库,则可以参考特定于驱动程序的第二个选项(例如pg_prepare()
,pg_execute()
对于PostgreSQL)。PDO是通用选项。
正确设置连接
请注意,在使用PDO
访问MySQL数据库时,默认情况下不使用实际准备好的语句。要解决此问题,您必须禁用预准备语句的模拟。使用PDO创建连接的示例是:
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
在上面的例子中,错误模式并不是绝对必要的,但建议添加它。这样,Fatal Error
当出现问题时,脚本不会停止。并且它为开发人员提供了catch
任何throw
n为PDOException
s的错误的机会。
什么是强制性的,但是,是第一setAttribute()
线,它告诉PDO禁用模拟预处理语句和使用真正准备好的语句。这可以确保PHP在将语句和值发送到MySQL服务器之前不会解析它(使攻击者可能无法注入恶意SQL)。
虽然您可以charset
在构造函数的选项中进行设置,但重要的是要注意PHP的旧版本(<5.3.6)默认忽略 DSN中的charset参数。
说明
会发生什么是您传递给的SQL语句prepare
由数据库服务器解析和编译。通过指定参数(如上例中的a ?
或命名参数:name
),您可以告诉数据库引擎要过滤的位置。然后,当您调用时execute
,预准备语句将与您指定的参数值组合。
这里重要的是参数值与编译语句结合,而不是SQL字符串。SQL注入通过在创建SQL以发送到数据库时欺骗脚本来包含恶意字符串。因此,通过从参数中单独发送实际SQL,可以限制最终出现您不想要的内容的风险。使用预准备语句时发送的任何参数都将被视为字符串(尽管数据库引擎可能会进行一些优化,因此参数最终也可能作为数字)。在上面的示例中,如果$name
变量包含'Sarah'; DELETE FROM employees
结果,那么只需要搜索字符串"'Sarah'; DELETE FROM employees"
,您就不会得到一个空表。
使用预准备语句的另一个好处是,如果在同一个会话中多次执行相同的语句,它只会被解析和编译一次,从而为您带来一些速度提升。
如果你问过如何为插入操作,这是一个例子(使用PDO):
$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');
$preparedStatement->execute(array('column' => $unsafeValue));
准备好的语句可以用于动态查询吗?
虽然您仍然可以为查询参数使用预准备语句,但动态查询本身的结构无法进行参数化,并且某些查询功能无法进行参数化。
对于这些特定方案,最好的办法是使用限制可能值的白名单过滤器:
// Value whitelist
// $dir can only be 'DESC' otherwise it will be 'ASC'
if (empty($dir) || $dir !== 'DESC') {
$dir = 'ASC';
}
版权声明:
作者:Kiwi
链接:https://www.qingwei.tech/programe-develops/1364.html
来源:清渭技术小站
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论