PHP防范SQL注入的具体方法
什么是SQL注入(SQL Injection)
所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击。
防护
归纳一下,主要有以下几点:
1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和双"-"进行转换等。
2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
6.sql注入的检测方法一般采取辅助软件或网站平台来检测,个人采用 PHP代码审计系统—RIPS
PHP防范SQL注入
强制字符格式(类型)
在很多时候我们要用到类似xxx.php?id=xxx这样的URL,一般来说$id都是整型变量,为了防范攻击者把$id篡改成攻击语句,我们要尽量强制变量,代码如下:
$id=intval($_GET['id']);
当然,还有其他的变量类型,如果有必要的话尽量强制一下格式。
SQL语句中包含变量加引号
这一点儿很简单,但也容易养成习惯,先来看看这两条SQL语句:
SQL代码
SELECT * FROM article WHERE articleid=$id
两种写法在各种程序中都很普遍,但安全性是不同的,第一句由于把变量$id放在一对单引号中,这样使得我们所提交的变量都变成了字符串,即使包含了正确的SQL语句,也不会正常执行,而第二句不同,由于没有把变量放进单引号中,那我们所提交的一切,只要包含空格,那空格后的变量都会作为SQL语句执行,因此,我们要养成给SQL语句中变量加引号的习惯。
对输入的字符串进行转义处理
/**
* 函数名称:check_input()
* 函数作用:对提交的字符串进行过滤
* 参 数:$value: 要处理的字符串
* 返 回 值:返回过滤后的字符串
*/
function check_input($value){
if (get_magic_quotes_gpc()){
$value = stripslashes($value);
}
$value = mysql_real_escape_string($value);
//$value = addslashes($value);
//$value = str_replace ( "_", "\_", $value ); // 把 '_'过滤掉
// $value = str_replace ( "%", "\%", $value ); // 把 '%'过滤掉
return $value;
}
对输出的字符串进行实例化处理
/**
* 函数名称:check_output()
* 函数作用:对输出的内容进行处理
* 参 数:$value: 要输出的内容
* 返 回 值:返回过滤后的内容
*/
function check_output($value){
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
return $value;
}