【总结】SQL注入防护手段
1、对提交的数据进行数据类型判断,比如id值必须是数字:is_numeric($id)
2、对提交的数据进行正则匹配,禁止出现注入语句,比如union、or、and等
3、对提交数据进行特殊符号转义,比如单引号、双引号等,用addslash等函数加工一下
4、不使用sql语句拼接参数的方式来执行sql语句,而是用参数化查询,也叫做参数绑定的方式,对提交的参数进行预编译然后进行参数绑定,这样会将用户提交的注入语句作为参数值来处理,而不是当作sql语句执行,这样可以有效的方法sql注入:不同语言的写法不同,但是原理相同。
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id',$id, PDO::PARAM_INT );
$data->execute();
但是预编译也不能完全解决sql注入问题,比如如果查询语句中表名是动态的,也就是说表名也是用户可以提交过来的数据,根据用户提交的表名来进行不同表数据的查询,那么也会出现sql注入漏洞,因为表名不能进行预编译及参数绑定,下面就报错
$table_name='vince';
$data = $db->prepare( 'SELECT first_name, last_name FRoM (:table_name) wHERE user_id = (:id) LIMIT 1;'
);
这种就需要配合白名单进行过滤:
if ($table_name == 'vince'){
$data = $db->prepare( 'SELECT first_name, last_name FRoM jaden WHERE user_id = (:id) LIMIT 1;' );
}elif ($table_name =='wulaoban'){
$data = $db->prepare( 'SELECT first_name, last_name FROM wulaoban wHERE user_id = (:id) LIMIT 1;' );
}else{
echo '别乱搞!';
}
5、分级管理:用户的权限要进行严格控制和划分,服务端代码连接数据库使用的用户禁止使用root等高权限用户。比如对用户进行分级管理,严格控制用户的权限,对于普通用户,禁止给子数据库建立、删除、修改等相关权限,只有系统管理员才具有增、删、改、查的权限等等。
6、数据库中敏感的数据,比如用户的密码,要加密存储。
总体来说:
(1)永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对特殊字符和符号进行转换等。
(2)永远不要使用动态拼装SQL,可以使用参数化的SQL或者直接使用存储过程进行数据查询存取。
(3)永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
(4)不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息。
(5)应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装,把异常信息存放在独立的表中。