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 操作文件的一些FAQ总结
Feb 12 PHP
php foreach 参数强制类型转换的问题
Dec 10 PHP
php入门学习知识点四 PHP正则表达式基本应用
Jul 14 PHP
PHP判断指定时间段的2个方法
Mar 14 PHP
php实现mysql备份恢复分卷处理的方法
Dec 26 PHP
php开发时容易忘记的一些技术细节
Feb 03 PHP
php编程每天必学之表单验证
Mar 01 PHP
利用ajax和PHP实现简单的流程管理
Mar 23 PHP
php解压缩zip和rar压缩包文件的方法
Jul 10 PHP
Laravel框架创建路由的方法详解
Sep 04 PHP
redis+php实现微博(一)注册与登录功能详解
Sep 23 PHP
安装PHP扩展时解压官方 tgz 文件后没有configure文件无法进行配置编译的问题
Aug 26 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判断用户是否关注微信公众号
2016/07/22 PHP
详解Yii2.0 rules验证规则集合
2017/03/21 PHP
PHP+jQuery实现滚屏无刷新动态加载数据功能详解
2017/05/04 PHP
PHP实现数组转JSon和JSon转数组的方法示例
2018/06/14 PHP
PHP使用SOAP调用API操作示例
2018/12/25 PHP
JavaScript 保存数组到Cookie的代码
2010/04/14 Javascript
清空上传控件input file的值
2010/07/03 Javascript
jQuery学习笔记之 Ajax操作篇(三) - 过程处理
2014/06/23 Javascript
node.js中的buffer.copy方法使用说明
2014/12/14 Javascript
JavaScript计时器示例分析
2015/02/05 Javascript
AngularJS入门教程之ng-checked 指令详解
2016/08/01 Javascript
javascript实现二叉树遍历的代码
2017/06/08 Javascript
使用JavaScript实现点击循环切换图片效果
2017/09/03 Javascript
vue-swiper的使用教程
2018/08/30 Javascript
微信小程序定义和调用全局变量globalData的实现
2019/11/01 Javascript
js blob类型url的视频下载问题的解决
2019/11/29 Javascript
Vue快速实现通用表单验证的示例代码
2020/01/09 Javascript
通过实例了解Nodejs模块系统及require机制
2020/07/16 NodeJs
JS如何监听div的resize事件详解
2020/12/03 Javascript
python设置检查点简单实现代码
2014/07/01 Python
详解Python程序与服务器连接的WSGI接口
2015/04/29 Python
Python实现针对含中文字符串的截取功能示例
2017/09/22 Python
Python爬取腾讯视频评论的思路详解
2019/12/19 Python
Python处理mysql特殊字符的问题
2020/03/02 Python
html5 canvas绘制矩形和圆形的实例代码
2016/06/16 HTML / CSS
Crucial英睿达法国官网:内存条及SSD固态硬盘升级
2018/07/13 全球购物
汽车维修专业毕业生的求职信分享
2013/12/04 职场文书
会计系个人求职信范文分享
2013/12/20 职场文书
学校后勤岗位职责
2014/02/19 职场文书
企业党员个人自我评价
2014/09/20 职场文书
群众路线对照检查剖析材料
2014/10/09 职场文书
学校安全管理制度
2015/08/06 职场文书
使用Oracle跟踪文件的问题详解
2021/06/28 Oracle
Python常遇到的错误和异常
2021/11/02 Python
Python实现GIF动图以及视频卡通化详解
2021/12/06 Python
使用Bandicam录制鼠标指针并附带点击声音,还可以添加点击动画效果
2022/04/11 数码科技