php xfocus防注入资料


Posted in PHP onApril 27, 2008

这里没有太深的技术含量,我只是比较简单的谈了谈。(以下操作如无具体说 明,都是基于PHP+MySQL+Apache的情况) 在现在各种黑客横行的时候,如何实现自己php代码安全,保证程序和服务器的安全是一个很重要的问题,我随便看了下关于php安全的资料,并不是很 多,至少比asp少多了,呵呵,于是就想写点东西,来防止这些可能出现的情况。这里没有太深的技术含量,我只是比较简单的谈了谈。(以下操作如无具体说 明,都是基于PHP+MySQL+Apache的情况) 
    先来说说安全问题,我们首先看一下两篇文章:
http://www.xfocus.net/articles/200107/227.html     
http://www.xfocus.net/articles/200107/228.html

    上面文章是安全焦点上的关于PHP安全的文章,基本上比较全面的介绍了关于PHP的一些安全问题。

    在PHP编码的时候,如果考虑到一些比较基本的安全问题,首先一点:
1. 初始化你的变量

    为什么这么说呢?我们看下面的代码:
if ($admin)
{
    echo '登陆成功!';
    include('admin.php');
}
else
{
    echo '你不是管理员,无法进行管理!';
}

    好,我们看上面的代码好像是能正常运行,没有问题,那么加入我提交一个非法的参数过去呢,那么效果会如何呢?比如我们的这个页是 http://www.traget.com/login.php,那么我们提交:http://www.target.com/login.php?admin=1,呵呵,你想一些,我们是不是直接就是管理员了,直接进行管理。
    当然,可能我们不会犯这么简单错的错误,那么一些很隐秘的错误也可能导致这个问题,比如最近暴出来的phpwind 1.3.6论坛有个漏洞,导致能够直接拿到管理员权限,就是因为有个$skin变量没有初始化,导致了后面一系列问题。

    那么我们如何避免上面的问题呢?首先,从php.ini入手,把php.ini里面的register_global = off,就是不是所有的注册变量为全局,那么就能避免了。但是,我们不是服务器管理员,只能从代码上改进了,那么我们如何改进上面的代码呢?我们改写如 下:
$admin = 0;      // 初始化变量
if ($_POST['admin_user'] && $_POST['admin_pass'])
{
    // 判断提交的管理员用户名和密码是不是对的相应的处理代码
    // ...
    $admin = 1;
}
else
{
    $admin = 0;
}

if ($admin)
{
    echo '登陆成功!';
    include('admin.php');
}
else
{
    echo '你不是管理员,无法进行管理!';
}

    那么这时候你再提交 http://www.target.com/login.php?admin=1 就不好使了,因为我们在一开始就把变量初始化为 $admin = 0 了,那么你就无法通过这个漏洞获取管理员权限。

2. 防止SQL Injection (sql注射)

    SQL 注射应该是目前程序危害最大的了,包括最早从asp到php,基本上都是国内这两年流行的技术,基本原理就是通过对提交变量的不过滤形成注入点然后使恶意用户能够提交一些sql查询语句,导致重要数据被窃取、数据丢失或者损坏,或者被入侵到后台管理。
基本原理我就不说了,我们看看下面两篇文章就很明白了:
http://www.4ngel.net/article/36.htm
http://www.4ngel.net/article/30.htm

    那么我们既然了解了基本的注射入侵的方式,那么我们如何去防范呢?这个就应该我们从代码去入手了。

    我们知道Web上提交数据有两种方式,一种是get、一种是post,那么很多常见的sql注射就是从get方式入手的,而且注射的语句里面一定是包含一些sql语句的,因为没有sql语句,那么如何进行,sql语句有四大句:
    select 、update、delete、insert,那么我们如果在我们提交的数据中进行过滤是不是能够避免这些问题呢?
    于是我们使用正则就构建如下函数:

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

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

if (inject_check($_GET['id']))
{
     exit('你提交的数据非法,请检查后重新提交!');
}
else
{
    $id = $_GET['id'];
    echo '提交的数据合法,请继续!';
}
?>
    假设我们提交URL为:http://www.target.com/a.php?id=1,那么就会提示:
    "提交的数据合法,请继续!"
    如果我们提交 http://www.target.com/a.php?id=1' select * from tb_name
    就会出现提示:"你提交的数据非法,请检查后重新提交!"

    那么就达到了我们的要求。

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

/*
函数名称:verify_id()
函数作用:校验提交的ID类值是否合法
参        数:$id: 提交的ID值
返 回 值:返回处理后的ID
函数作者:heiyeluren
*/
function verify_id($id=null)
{
   if (!$id) { exit('没有提交参数!'); }    // 是否为空判断
   elseif (inject_check($id)) { exit('提交的参数非法!'); }    // 注射判断
   elseif (!is_numeric($id)) { exit('提交的参数非法!'); }    // 数字判断
   $id = intval($id);    // 整型化

   return  $id;
}

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

if (inject_check($_GET['id']))
{
     exit('你提交的数据非法,请检查后重新提交!');
}
else
{
    $id = verify_id($_GET['id']);    // 这里引用了我们的过滤函数,对$id进行过滤
    echo '提交的数据合法,请继续!';
}
?>

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

/*
函数名称:str_check()
函数作用:对提交的字符串进行过滤
参    数:$var: 要处理的字符串
返 回 值:返回过滤后的字符串
函数作者:heiyeluren
*/
function str_check( $str )
{
   if (!get_magic_quotes_gpc())    // 判断magic_quotes_gpc是否打开
   {
      $str = addslashes($str);    // 进行过滤
}
     $str = str_replace("_", "_", $str);    // 把 '_'过滤掉
     $str = str_replace("%", "%", $str);    // 把' % '过滤掉

   return $str; 
}

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

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

/*
函数名称:post_check()
函数作用:对提交的编辑内容进行处理
参    数:$post: 要提交的内容
返 回 值:$post: 返回过滤后的内容
函数作者:heiyeluren
*/
function post_check($post)
{
   if (!get_magic_quotes_gpc())    // 判断magic_quotes_gpc是否为打开
   {
      $post = addslashes($post);    // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤
   }
   $post = str_replace("_", "_", $post);    // 把 '_'过滤掉
   $post = str_replace("%", "%", $post);    // 把' % '过滤掉
   $post = nl2br($post);    // 回车转换
   $post= htmlspecialchars($post);    // html标记转换

   return $post;
}

    呵呵,基本到这里,我们把一些情况都说了一遍,其实我觉得自己讲的东西还很少,至少我才只讲了两方面,再整个安全中是很少的内容了,考虑下一次讲更多,包括php安全配置,apache安全等等,让我们的安全正的是一个整体,作到最安全。

    最后在告诉你上面表达的:1. 初始化你的变量  2. 一定记得要过滤你的变量

PHP 相关文章推荐
使用PHP数组实现无限分类,不使用数据库,不使用递归.
Dec 09 PHP
ie6 动态缩略图不显示的原因
Jun 21 PHP
有关JSON以及JSON在PHP中的应用
Apr 09 PHP
php array_pop()数组函数将数组最后一个单元弹出(出栈)
Jul 12 PHP
关于尾递归的使用详解
May 02 PHP
完美解决令人抓狂的zend studio 7代码提示(content Assist)速度慢的问题
Jun 20 PHP
PHP随机字符串生成代码(包括大小写字母)
Jun 24 PHP
纯PHP生成的一个树叶图片画图例子
Apr 16 PHP
ThinkPHP整合百度Ueditor图文教程
Oct 21 PHP
thinkphp中AJAX返回ajaxReturn()方法分析
Dec 06 PHP
PHP实现用户登录的案例代码
May 10 PHP
PDO::errorCode讲解
Jan 28 PHP
php SQL防注入代码集合
Apr 25 #PHP
php中文字母数字验证码实现代码
Apr 25 #PHP
Ajax PHP简单入门教程代码
Apr 25 #PHP
PHP开发框架总结收藏
Apr 24 #PHP
php5数字型字符串加解密代码
Apr 24 #PHP
php实现的简单压缩英文字符串的代码
Apr 24 #PHP
php格式化工具Beautify PHP小小BUG
Apr 24 #PHP
You might like
php 防止单引号,双引号在接受页面转义
2008/07/10 PHP
解析php防止form重复提交的方法
2013/07/01 PHP
php将字符串随机分割成不同长度数组的方法
2015/06/01 PHP
php实现倒计时效果
2015/12/19 PHP
javascript函数库-集合框架
2007/04/27 Javascript
jquery tools系列 expose 学习
2009/09/06 Javascript
JavaScript 学习初步 入门教程
2010/03/25 Javascript
div层的移动及性能优化
2010/11/16 Javascript
小试JQuery的AutoComplete插件
2011/05/04 Javascript
求数组最大最小值方法适用于任何数组
2013/08/16 Javascript
JavaScript执行顺序详细介绍
2013/12/04 Javascript
jQuery CSS()方法改变现有的CSS样式
2014/08/20 Javascript
JavaScript中的Math.LN2属性用法详解
2015/06/12 Javascript
jquery实现超简洁的TAB选项卡效果代码
2015/08/28 Javascript
div中文字内容溢出常见的解决方法
2017/03/16 Javascript
基于AngularJS的简单使用详解
2017/09/10 Javascript
vue axios同步请求解决方案
2017/09/29 Javascript
浅谈webpack 构建性能优化策略小结
2018/06/13 Javascript
vue 自定义指令自动获取文本框焦点的方法
2018/08/25 Javascript
python持久性管理pickle模块详细介绍
2015/02/18 Python
在Python的Flask框架中使用模版的入门教程
2015/04/20 Python
将Python代码嵌入C++程序进行编写的实例
2015/07/31 Python
使用python在本地电脑上快速处理数据
2017/06/22 Python
Python爬虫信息输入及页面的切换方法
2018/05/11 Python
详解Python网络框架Django和Scrapy安装指南
2019/04/01 Python
python使用opencv实现马赛克效果示例
2019/09/28 Python
Python常见反爬虫机制解决方案
2020/06/01 Python
python3.7.3版本和django2.2.3版本是否可以兼容
2020/09/01 Python
有模特经验的简历自我评价
2013/09/19 职场文书
学生实习推荐信范文
2013/11/26 职场文书
教师个人年度总结
2015/02/11 职场文书
三好学生个人总结
2015/02/15 职场文书
2015年学校管理工作总结
2015/07/20 职场文书
2015小学教育教学工作总结
2015/07/21 职场文书
JavaScript 去重和重复次数统计
2021/03/31 Javascript
MySQL系列之十五 MySQL常用配置和性能压力测试
2021/07/02 MySQL