houmin0036

如果把用户输入的没有任何改动的放到SQL的查询语句中,很有可能会导致SQL注入,比如说下面的例子:

$unsafe_variable = $_POST[\'user_input\']; 
mysql_query("INSERT INTO `table` (`column`) VALUES (\'$unsafe_variable\')");

为什么会有注入漏洞呢?因为用户可以输入value\'); DROP TABLE table;#...然后查询语句就变成了这样:

INSERT INTO `table` (`column`) VALUES (\'value\'); DROP TABLE table;#...\')

可以采用PDO预处理语句加参数化查询方法预防SQL注入攻击:

参数化查询(Parameterized Query或Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数(Parameter)来给值,这个方法目前已被视为最有效可预防SQL注入攻击的攻击手法的防御方式。

除了安全因素,相比起拼接字符串的SQL语句,参数化的查询往往有性能优势。因为参数化的查询能让不同的数据通过参数到达数据库,从而公用同一条SQL语句。大多数数据库会缓存解释SQL语句产生的字节码而省下重复解析的开销。如果采取拼接字符串的SQL语句,则会由于操作数据是SQL语句的一部分而非参数的一部分,而反复大量解释SQL语句产生不必要的开销。

原理 在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才应用参数运行,因此就算参数中含有具破坏性的指令,也不会被数据库所运行。

举例:

// 实例化数据抽象层对象
$db = new PDO(\'pgsql:host=127.0.0.1;port=5432;dbname=testdb\');
// 对SQL语句执行prepare,得到PDOStatement对象
$stmt = $db->prepare(\'SELECT * FROM "myTable" WHERE "id" = :id AND "is_valid" = :is_valid\');
// 绑定参数
$stmt->bindValue(\':id\', $id);
$stmt->bindValue(\':is_valid\', true);
// 查询
$stmt->execute();
// 获取数据
foreach($stmt as $row) {
    var_dump($row);
}

 

分类:

技术点:

相关文章: