当前位置:首页 > PHP教程 > php高级应用 > 列表

php安全之防注入详细介绍

发布:smiling 来源: PHP粉丝网  添加日期:2014-08-23 11:09:29 浏览: 评论:0 

我们知道Web上提交数据有两种方式,一种是get、一种是post,那么很多常见的sql注射就是从get方式入手的,而且注射的语句里面一定是包含一些sql语句的,因为没有sql语句,那么如何进行,sql语句有四大句:select、update、delete、insert.

那么我们如果在我们提交的数据中进行过滤是不是能够避免这些问题呢?于是我们使用正则就构建如下函数,代码如下:

  1. /* 
  2. 函数名称:inject_check() 
  3. 函数作用:检测提交的值是不是含有SQL注射的字符,防止注射,保护服务器安全 
  4. 参 数:$sql_str: 提交的变量 
  5. 返 回 值:返回检测结果,ture or false 
  6. 函数作者:heiyeluren 
  7. */ 
  8. //开源代码phpfensi.com 
  9. function inject_check($sql_str)  
  10. {  
  11.      return eregi('select|insert|update|delete|'|/*|*|../|./|union|into|load_file|outfile', $sql_str);    // 进行过滤  
  12.  }  

我们函数里把 select,insert,update,delete,union,into,load_file,outfile /*, ./ , ../ , ' 等等危险的参数字符串全部过滤掉,那么就能够控制提交的参数了,程序可以这么构建,代码如下:

  1. <?php 
  2. if (inject_check($_GET['id']))
  3. {
  4.   exit('你提交的数据非法,请检查后重新提交!');
  5. }
  6. else
  7. {
  8.   $id = $_GET['id'];
  9.   echo '提交的数据合法,请继续!';
  10. }
  11. ?> 

假设我们提交URL为:a.php?id=1,那么就会提示:

"提交的数据合法,请继续!",如果我们提交 a.php?id=1%27 select * from tb_name,就会出现提示:"你提交的数据非法,请检查后重新提交!",那么就达到了我们的要求.

但是,问题还没有解决,假如我们提交的是 a.php?id=1asdfasdfasdf 呢,我们这个是符合上面的规则的,但是呢,它是不符合要求的,于是我们为了可能其他的情况,我们再构建一个函数来进行检查,代码如下:

  1. /* 
  2. 函数名称:verify_id() 
  3. 函数作用:校验提交的ID类值是否合法 
  4. 参 数:$id: 提交的ID值 
  5. 返 回 值:返回处理后的ID 
  6. 函数作者:heiyeluren 
  7. */ 
  8. function verify_id($id=null)  
  9. {  
  10.  
  11.    if (!$id) { exit('没有提交参数!'); }    // 是否为空判断  
  12.  
  13.    elseif (inject_check($id)) { exit('提交的参数非法!'); }    // 注射判断  
  14.  
  15.    elseif (!is_numeric($id)) { exit('提交的参数非法!'); }    // 数字判断  
  16.  
  17.    $id = intval($id);    // 整型化  
  18.  
  19.    return  $id;  
  20.  

呵呵,那么我们就能够进行校验了,于是我们上面的程序代码就变成了下面的:

  1. <?php
  2. if (inject_check($_GET['id']))
  3. {
  4.    exit('你提交的数据非法,请检查后重新提交!');
  5. }
  6. else
  7. {
  8.   $id = verify_id($_GET['id']);    // 这里引用了我们的过滤函数,对$id进行过滤  
  9.  echo '提交的数据合法,请继续!'; 
  10. }
  11. ?> 

好,问题到这里似乎都解决了,但是我们有没有考虑过post提交的数据,大批量的数据呢?

比如一些字符可能会对数据库造成危害,比如 ' _ ', ' % ',这些字符都有特殊意义,那么我们如果进行控制呢?还有一点,就是当我们的php.ini里面的magic_quotes_gpc = off 的时候,那么提交的不符合数据库规则的数据都是不会自动在前面加' '的,那么我们要控制这些问题,于是构建如下函数,代码如下:

  1. /* 
  2. 函数名称:str_check() 
  3. 函数作用:对提交的字符串进行过滤 
  4. 参 数:$var: 要处理的字符串 
  5. 返 回 值:返回过滤后的字符串 
  6. 函数作者:heiyeluren 
  7. */ 
  8.  
  9. function str_check( $str )  
  10.  
  11. {  
  12.  
  13.    if (!get_magic_quotes_gpc())    // 判断magic_quotes_gpc是否打开  
  14.  
  15.    {  
  16.  
  17.       $str = addslashes($str);    // 进行过滤  
  18.  
  19.  }  
  20.  
  21.      $str = str_replace("_""_"$str);    // 把 '_'过滤掉  
  22.  
  23.      $str = str_replace("%""%"$str);    // 把' % '过滤掉 
  24.   
  25.    return $str;   
  26.  
  27. }  

OK,我们又一次的避免了服务器被沦陷的危险.

最后,再考虑提交一些大批量数据的情况,比如发贴,或者写文章、新闻,我们需要一些函数来帮我们过滤和进行转换,再上面函数的基础上,我们构建如下函数,代码如下:

  1. /* 
  2. 函数名称:post_check() 
  3. 函数作用:对提交的编辑内容进行处理 
  4. 参 数:$post: 要提交的内容 
  5. 返 回 值:$post: 返回过滤后的内容 
  6. 函数作者:heiyeluren 
  7. */ 
  8. //开源代码phpfensi.com 
  9. function post_check($post)  
  10.  
  11. {  
  12.  
  13.    if (!get_magic_quotes_gpc())    // 判断magic_quotes_gpc是否为打开  
  14.  
  15.    {  
  16.  
  17.       $post = addslashes($post);    // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤  
  18.  
  19.    }  
  20.  
  21.    $post = str_replace("_""_"$post);    // 把 '_'过滤掉  
  22.  
  23.    $post = str_replace("%""%"$post);    // 把' % '过滤掉  
  24.  
  25.    $post = nl2br($post);    // 回车转换  
  26.  
  27.    $post= htmlspecialchars($post);    // html标记转换  
  28.  
  29.    return $post;  
  30.  
  31. }  

Tags: php安全 PHP防注入

分享到: