PHP中防止SQL注入实现代码

说到网站安全就不得不提到SQL注入(SQL Injection),如果你用过ASP,对SQL注入一定有比较深的理解,PHP的安全性相对较高,这是因为MYSQL4以下的版本不支持子语句,而且当php.ini里的 magic_quotes_gpc 为On 时。

提交的变量中所有的 ' (单引号), " (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符,给SQL注入带来不少的麻烦。

请看清楚:“麻烦”而已~这并不意味着PHP防范SQL注入,书中就讲到了利用改变注入语句的编码来绕过转义的方法,比如将SQL语句转成ASCII编码(类似:char(100,58,92,108,111,99,97,108,104,111,115,116…)这样的格式),或者转成16进制编码,甚至还有其他形式的编码,这样以来,转义过滤便被绕过去了,那么怎样防范呢:

 

a. 打开magic_quotes_gpc或使用addslashes()函数

 

在新版本的PHP中,就算magic_quotes_gpc打开了,再使用addslashes()函数,也不会有冲突,但是为了更好的实现版本兼容,建议在使用转移函数前先检测magic_quotes_gpc状态,或者直接关掉,代码如下:

PHP防范SQL注入的代码

 
 
  1. // 去除转义字符   
  2. function stripslashes_array($array) {   
  3. if (is_array($array)) {   
  4. foreach ($array as $k => $v) {   
  5. $array[$k] = stripslashes_array($v);   
  6. }   
  7. } else if (is_string($array)) {   
  8. $array = stripslashes($array);   
  9. }   
  10. return $array;   
  11. }   
  12. @set_magic_quotes_runtime(0);   
  13. // 判断 magic_quotes_gpc 状态   
  14. if (@get_magic_quotes_gpc()) {   
  15. $_GET = stripslashes_array($_GET);   
  16. $_POST = stripslashes_array($_POST);   
  17. $_COOKIE = stripslashes_array($_COOKIE);   
  18. }  

去除magic_quotes_gpc的转义之后再使用addslashes函数,代码如下:

PHP防范SQL注入的代码

$keywords = addslashes($keywords); 
$keywords = str_replace("_","\_",$keywords);//转义掉”_” 
$keywords = str_replace("%","\%",$keywords);//转义掉”%”

后两个str_replace替换转义目的是防止黑客转换SQL编码进行攻击。

 

b. 强制字符格式(类型)

 

在很多时候我们要用到类似xxx.php?id=xxx这样的URL,一般来说$id都是整型变量,为了防范攻击者把$id篡改成攻击语句,我们要尽量强制变量,代码如下:

PHP防范SQL注入的代码

$id=intval($_GET[‘id’]);

当然,还有其他的变量类型,如果有必要的话尽量强制一下格式。

 

c. SQL语句中包含变量加引号

 

这一点儿很简单,但也容易养成习惯,先来看看这两条SQL语句:

SQL代码

SELECT * FROM article WHERE articleid='$id' 
SELECT * FROM article WHERE articleid=$id

两种写法在各种程序中都很普遍,但安全性是不同的,第一句由于把变量$id放在一对单引号中,这样使得我们所提交的变量都变成了字符串,即使包含了正确的SQL语句,也不会正常执行,而第二句不同,由于没有把变量放进单引号中,那我们所提交的一切,只要包含空格,那空格后的变量都会作为SQL语句执行,因此,我们要养成给SQL语句中变量加引号的习惯。

d.URL伪静态化

URL伪静态化也就是URL重写技术,像Discuz!一样,将所有的URL都rewrite成类似xxx-xxx-x.html格式,既有利于SEO,又达到了一定的安全性,也不失为一个好办法。但要想实现PHP防范SQL注入,前提是你得有一定的“正则”基础。




 

<1>addslashes 指定的预定义字符串(单引号(')、双引号(")、反斜线(\)与 NUL )前面加反斜杠

一个使用 addslashes() 的例子是当你要往数据库中输入数据时。例如,将名字 O'reilly 插入到数据库中,

这就需要对其进行转义。大多数据库使用 \ 作为转义符:O\'reilly。

这样可以将数据放入数据库中,而不会插入额外的 \。

当 PHP 指令 magic_quotes_sybase 被设置成 on 时,意味着插入 ' 时将使用 ' 进行转义。 

默认情况下,PHP 指令 magic_quotes_gpc 为 on,

它主要是对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。

不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes(),

因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。

function addslashes_deep($value) 

{

    if (empty($value)) 

{

        return $value;  //如为空,直接返回;

    } 

else 

{

//递归处理数组,直至遍历所有数组元素;

        return is_array($value) ? array_map('addslashes_deep', $value): addslashes($value);

    }  

}

<2>set_magic_quotes_runtime

\ " ' 这样的字符要写入到数据库里面,又想不被过滤掉的时候

set_magic_quotes_runtime是用来设置PHP 环境配置的变量 magic_quotes_runtime 值。0-关闭 1-打开

get_magic_quotes_runtime,返回 0 表示关闭本功能;返回 1 表示本功能打开

<3>mysql_escape_string 类似于addslashes


你可能感兴趣的:(PHP中防止SQL注入实现代码)