PHP和XSS跨站攻击的防范


Posted in PHP onApril 17, 2007

其实这个话题很早就想说说了,发现国内不少PHP站点都有XSS漏洞。今天偶然看到PHP5的一个XSS漏洞,在此小结一下。顺便提醒,使用PHP5的朋友最好打下补丁,或者升级一下。

如果你不懂什么是XSS,可以看这里,或者这里(中文的也许会好懂一些)。

国内不少论坛都存在跨站脚本漏洞,例如这里  有一个Google Hack+XSS的攻击例子,针对的是Discuz 4.0.0RC3。国外也很多这样的例子,甚至Google也出现过,不过在12月初时修正了。跨站攻击很容易就可以构造,而且非常隐蔽,不易被查觉(通常盗取信息后马上跳转回原页面)。
如何攻击,在此不作说明(也不要问我),主要谈谈如何防范。首先,跨站脚本攻击都是由于对用户的输入没有进行严格的过滤造成的,所以我们必须在所有数据进入我们的网站和数据库之前把可能的危险拦截。针对非法的HTML代码包括单双引号等,可以使用htmlentities() 。

<?php
$str = "A 'quote' is <b>bold</b>";

// Outputs: A 'quote' is <b>bold</b>
echo htmlentities($str);

// Outputs: A 'quote' is <b>bold</b>
echo htmlentities($str, ENT_QUOTES);
?>

这样可以使非法的脚本失效。

但是要注意一点,htmlentities()默认编码为 ISO-8859-1,如果你的非法脚本编码为其它,那么可能无法过滤掉,同时浏览器却可以识别和执行。这个问题我先找几个站点测试后再说。

这里提供一个过滤非法脚本的函数:

function RemoveXSS($val) { 
   // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed 
   // this prevents some character re-spacing such as <java\0script> 
   // note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs 
   $val = preg_replace('/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val); 

   // straight replacements, the user should never need these since they're normal characters 
   // this prevents like <IMG SRC=@avascript:alert('XSS')> 
   $search = 'abcdefghijklmnopqrstuvwxyz'; 
   $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
   $search .= '1234567890!@#$%^&*()'; 
   $search .= '~`";:?+/={}[]-_|\'\\'; 
   for ($i = 0; $i < strlen($search); $i++) { 
      // ;? matches the ;, which is optional 
      // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars 

      // @ @ search for the hex values 
      $val = preg_replace('/(&#[x|X]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ; 
      // @ @ 0{0,7} matches '0' zero to seven times 
      $val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ; 
   } 

   // now the only remaining whitespace attacks are \t, \n, and \r 
   $ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base'); 
   $ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload'); 
   $ra = array_merge($ra1, $ra2); 

   $found = true; // keep replacing as long as the previous round replaced something 
   while ($found == true) { 
      $val_before = $val; 
      for ($i = 0; $i < sizeof($ra); $i++) { 
         $pattern = '/'; 
         for ($j = 0; $j < strlen($ra[$i]); $j++) { 
            if ($j > 0) { 
               $pattern .= '('; 
               $pattern .= '(&#[x|X]0{0,8}([9][a][b]);?)?'; 
               $pattern .= '|(�{0,8}([9][10][13]);?)?'; 
               $pattern .= ')?'; 
            } 
            $pattern .= $ra[$i][$j]; 
         } 
         $pattern .= '/i'; 
         $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag 
         $val = preg_replace($pattern, $replacement, $val); // filter out the hex tags 
         if ($val_before == $val) { 
            // no replacements were made, so exit the loop 
            $found = false; 
         } 
      } 
   } 
}

PHP 相关文章推荐
php 判断访客是否为搜索引擎蜘蛛的函数代码
Jul 29 PHP
PHP基础知识回顾
Aug 16 PHP
PHP设计模式之命令模式的深入解析
Jun 13 PHP
PHP防止post重复提交数据的简单例子
Jun 07 PHP
Yii2使用小技巧之通过 Composer 添加 FontAwesome 字体资源
Jun 22 PHP
php生成shtml类用法实例
Dec 09 PHP
VPS中使用LNMP安装WordPress教程
Dec 28 PHP
PHP中使用GD库绘制折线图 折线统计图的绘制方法
Nov 09 PHP
PHP封装的字符串加密解密函数
Dec 18 PHP
Laravel与CI框架中截取字符串函数
May 08 PHP
PHP单例模式与工厂模式详解
Aug 29 PHP
如何在PHP中使用数组
Jun 09 PHP
PHP与SQL注入攻击[三]
Apr 17 #PHP
PHP与SQL注入攻击[二]
Apr 17 #PHP
PHP与SQL注入攻击[一]
Apr 17 #PHP
使用Xdebug调试和优化PHP程序之[1]
Apr 17 #PHP
php下用GD生成生成缩略图的两个选择和区别
Apr 17 #PHP
15种PHP Encoder的比较
Apr 17 #PHP
dede全站URL静态化改造[070414更正]
Apr 17 #PHP
You might like
PHP数组操作汇总 php数组的使用技巧
2011/07/17 PHP
使用新浪微博API的OAuth认证发布微博实例
2015/03/27 PHP
yii2中结合gridview如何使用modal弹窗实例代码详解
2016/06/12 PHP
YII2框架中excel表格导出的方法详解
2017/07/21 PHP
JavaScript原型继承之基础机制分析
2011/08/26 Javascript
js 将json字符串转换为json对象的方法解析
2013/11/13 Javascript
form表单action提交的js部分与html部分
2014/01/07 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
2014/08/12 Javascript
轻量级的原生js日历插件calendar.js使用指南
2015/04/28 Javascript
javascript转换静态图片,增加粒子动画效果
2015/05/28 Javascript
Vue filter格式化时间戳时间成标准日期格式的方法
2018/09/16 Javascript
webpack+vue+express(hot)热启动调试简单配置方法
2018/09/19 Javascript
JavaScript作用域链实例详解
2019/01/21 Javascript
小程序显示弹窗时禁止下层的内容滚动实现方法
2019/03/20 Javascript
js 计算图片内点个数的示例代码
2019/04/04 Javascript
js中比较两个对象是否相同的方法示例
2019/09/02 Javascript
Layui表格行工具事件与数据回填方法
2019/09/13 Javascript
JS面向对象编程——ES6 中class的继承用法详解
2020/03/03 Javascript
vue element-ui中table合计指定列求和实例
2020/11/02 Javascript
[43:35]EG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
常见的python正则用法实例讲解
2016/06/21 Python
Python中shutil模块的常用文件操作函数用法示例
2016/07/05 Python
python使用pygame框架实现推箱子游戏
2018/11/20 Python
tensorflow使用range_input_producer多线程读取数据实例
2020/01/20 Python
详解python变量与数据类型
2020/08/25 Python
2013年入党人员的自我鉴定
2013/10/25 职场文书
暑期实习鉴定
2013/12/16 职场文书
民族团结先进个人材料
2014/02/05 职场文书
业务员简历自我评价
2014/03/06 职场文书
十佳党员事迹材料
2014/08/28 职场文书
小学生差生评语
2014/12/29 职场文书
学校会议通知范文
2015/04/15 职场文书
2015年普法依法治理工作总结
2015/05/26 职场文书
css3实现背景图片颜色修改的多种方式
2021/04/13 HTML / CSS
python中的被动信息搜集
2021/04/29 Python
PostgreSQL通过oracle_fdw访问Oracle数据的实现步骤
2021/05/21 PostgreSQL