SQL防注入

目标:编写动态的SQL查询

动态查询便是指将变量放到语句中,将固定的字符串和变量拼接在一块儿,组成一个完整的SQL查询语句,因为变量的值是动态变化的,所以查询也是动态的。编写这样的可以执行的动态的查询语句是十分天然的,也很是方便。可是,不经思考的加入也会带来很大的安全隐患。例如这样的一个查询:php

SELECT × FROM Bugs WHERE bug_id = $bug_id";

若是这个时候$bug_id = "1234; DELETE FROM Bugs",Bugs表就跪了。所以SQL注入的危害至关大,不能将未经验证的输入做为代码执行。mysql

作法

没有一种技术可以彻底的抵抗SQL注入,所以,须要将多种作法结合起来正则表达式

转义

转移能防止一些意外的状况,例如这个查询:sql

SELECT * FROM Projects WHERE project_name = '$project_name'

若是$project_name = O'Hare(这是很正常的一种状况),因为名字里面有个引号,查询就变成:数据库

SELECT * FROM Projects WHERE project_name = 'O'Hare'

这个时候数据库就会由于多了个引号而出错,所以须要在名字里面的'前加反斜杠。数组

参数化查询

参数化查询是指在编写查询语句的时候,在须要参数的位置上使用参数占位符,而后查询的时候提供这一参数。以php为例:安全

<?php

$sql = "SELECT * FROM Projects WHERE project_name = ?";
$stmt = mysqli_prepare($con, $sql);
mysqli_stmt_bind_param($stmt, 's', $_POST['name']);
mysqli_stmt_execute($stmt);

简单来讲,数据库接到一个指令,大体是这么作的:函数

  1. 编译SQL生成执行计划优化

  2. 选择执行计划code

  3. 执行

SQL注入不少状况是增长查询语句,增长查询语句就会形成查询的语义发生变化(就是说编译会生成不一样的东西)。若是使用参数化查询,在准备查询语句的时候数据库就去编译,而后提供参数就会重用这个编译结果,即便使用了注入变量,语义也不会发生变化(不会从新编译),同时,传参的时候,数据库也会将变量进行过滤,以达到防止注入的效果。

参数化查询也有作不到的东西:
1.多个值的列表不能做为单一参数
若是编写这么一个查询:

SELECT * FROM Bugs WHERE bug_id IN (?)

那么你传递参数的时候不能是“1234,3456,5678”这样的,这样会被认为是一个字符串
2.表名,列名,SQL关键字不能做为参数

过滤输入内容

应该将全部不合法的字符去掉,而不是找是否有些输入包含了危险的内容。
好比说若是是须要一个整数,就应该只是用变量里面的整数部分,(在Php里面有filter扩展),能够直接用类型转换函数,也能够用正则表达式匹配

给动态输入的值加引号

通常都用参数化查询,可是有时候,参数化查询会致使数据库采用错误的优化方案(多是采用错误的索引)。好比说表里面有一列99%的都是TRUE,那么用因此很快就能查询到那1%的FALSE。这个时候将变量直接插进去是好的作法。但这个时候就要格外当心的引用字符串。在php里面可使用PDO::quote()

用户与代码的隔离

好比说,你想要让用户选择究竟是按什么关键字排序,是升序排序,仍是按降序排序,这个时候你从客户端接受两个参数

<?php
$sort_standard = $_POST['order'];
$direction = $_POST['direction'];
$sql = "SELECT * FROM Bugs ORDER BY $sort_standard $direction";
mysqli_query($con, $sql);

可是这个并非一个安全的作法,由于用户能够传递任意值。可是参数化查询又不能是关键字,采用这样的作法:

先声明$sort_standard和$direction数组,好比这样

$sort_standard = array(
    "status" => "status",
    "date" => "date_report"
);
$direction = array(
    "up" => "ASC",
    "down" => "DESC"
);

当判断到用户的选择不在数组中的时候就使用默认值,若是在数组中就用对应值,这样作:

  1. 从不使用用户的输入进行查询,减小了注入风险

  2. 让语句动态化,而没有语法上的限制

  3. 将数据库查询和用户界面解藕

相关文章
相关标签/搜索