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 相关文章推荐
手把手教你使用DedeCms的采集的图文教程
Mar 11 PHP
PHP设计模式之装饰者模式
Feb 29 PHP
解析PHP 5.5 新特性
Jul 02 PHP
PHP下获取上个月、下个月、本月的日期(strtotime,date)
Feb 02 PHP
PHP、Nginx、Apache中禁止网页被iframe引用的方法
Oct 01 PHP
PHP实现定时执行任务的方法
Oct 05 PHP
PHP中的traits实现代码复用使用实例
May 13 PHP
Yii 2.0中场景的使用教程
Jun 02 PHP
PHP简单实现防止SQL注入的方法
Mar 13 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 PHP
php实现等比例压缩图片
Jul 26 PHP
PHP实现计算器小功能
Aug 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 循环列出目录内容的函数代码
2010/05/26 PHP
php读取excel文件示例分享(更新修改excel)
2014/02/27 PHP
php设计模式之单例模式实例分析
2015/02/25 PHP
PHP微信开发之文本自动回复
2016/06/23 PHP
php和C#的yield迭代器实现方法对比分析
2019/07/17 PHP
PhpSpreadsheet设置单元格常用操作汇总
2020/11/13 PHP
How to Auto Include a Javascript File
2007/02/02 Javascript
JS 创建对象(常见的几种方法)
2008/11/03 Javascript
javascript 强制刷新页面的实现代码
2009/12/13 Javascript
遍历jquery对象的代码分享
2011/11/02 Javascript
JS 获取select(多选下拉)中所选值的示例代码
2013/08/02 Javascript
JS 实现导航栏悬停效果
2013/09/23 Javascript
老生常谈遮罩层 滚动条的问题
2016/04/29 Javascript
JS实现表单多文件上传样式美化支持选中文件后删除相关项
2016/09/30 Javascript
自学实现angularjs依赖注入
2016/12/20 Javascript
基于vue2.0实现的级联选择器
2017/06/09 Javascript
使用JavaScript实现alert的实例代码
2017/07/06 Javascript
微信小程序实现随机验证码功能
2018/12/20 Javascript
[02:17]TI4西雅图DOTA2前线报道 啸天mik夫妻档解说
2014/07/08 DOTA
[51:22]Fnatic vs IG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python sys.argv用法实例
2015/05/28 Python
python编写微信远程控制电脑的程序
2018/01/05 Python
查看python下OpenCV版本的方法
2018/08/03 Python
python中时间、日期、时间戳的转换的实现方法
2019/07/06 Python
简单了解Django ContentType内置组件
2019/07/23 Python
在python中利用try..except来代替if..else的用法
2019/12/19 Python
浅析Python 责任链设计模式
2020/09/11 Python
爱游人:Travelliker
2017/09/05 全球购物
一些网络技术方面的面试题
2014/05/01 面试题
机关党员公开承诺书
2014/08/30 职场文书
学习党的群众路线实践活动思想汇报
2014/09/12 职场文书
“三支一扶”支教教师思想汇报
2014/09/13 职场文书
乡镇党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
中国梦宣传标语口号
2015/12/26 职场文书
观看安全警示教育片心得体会
2016/01/15 职场文书
Go 内联优化让程序员爱不释手
2022/06/21 Golang