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 相关文章推荐
杏林同学录(五)
Oct 09 PHP
用文本文件实现的动态实时发布新闻的程序
Oct 09 PHP
ubuntu12.04使用c编写php扩展模块教程分享
Dec 25 PHP
php mail to 配置详解
Jan 16 PHP
php分页函数完整实例代码
Sep 22 PHP
PHP扩展模块memcached长连接使用方法分析
Dec 24 PHP
php实现字符串首字母大写和单词首字母大写的方法
Mar 14 PHP
了解PHP的返回引用和局部静态变量
Jun 04 PHP
PHP整合PayPal支付
Jun 11 PHP
PHP配置把错误日志以邮件方式发送方法(Windows系统)
Jun 23 PHP
php实现查询功能(数据访问)
May 23 PHP
如何在centos8自定义目录安装php7.3
Nov 28 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 autoload与spl_autoload自动加载机制的深入理解
2013/06/05 PHP
PHP邮件发送类PHPMailer用法实例详解
2014/09/22 PHP
教你识别简单的免查杀PHP后门
2015/09/13 PHP
laravel使用Faker数据填充的实现方法
2019/04/12 PHP
如何在PHP环境中使用ProtoBuf数据格式
2020/06/19 PHP
jquery trim() 功能源代码
2011/02/14 Javascript
深入理解JavaScript作用域和作用域链
2011/10/21 Javascript
键盘上一张下一张兼容IE/google/firefox等浏览器
2014/01/28 Javascript
Javascript实现简单的富文本编辑器附演示
2014/06/16 Javascript
jQuery实现列表内容的动态载入特效
2015/08/08 Javascript
原生javascript实现自动更新的时间日期
2016/02/12 Javascript
JS用斜率判断鼠标进入DIV四个方向的方法
2016/11/07 Javascript
Angular2-primeNG文件上传模块FileUpload使用详解
2017/01/14 Javascript
jquery基于layui实现二级联动下拉选择(省份城市选择)
2017/06/20 jQuery
JS实现页面跳转与刷新的方法汇总
2019/08/30 Javascript
layui 实现表单和文件上传一起传到后台的例子
2019/09/16 Javascript
小程序实现投票进度条
2019/11/20 Javascript
使用AutoJs实现微信抢红包的代码
2020/12/31 Javascript
在Django的上下文中设置变量的方法
2015/07/20 Python
Python脚本实现12306火车票查询系统
2016/09/30 Python
Python字典简介以及用法详解
2016/11/15 Python
详解tensorflow实现迁移学习实例
2018/02/10 Python
python实现读Excel写入.txt的方法
2018/04/29 Python
Python实现判断一个整数是否为回文数算法示例
2019/03/02 Python
Windows10下Tensorflow2.0 安装及环境配置教程(图文)
2019/11/21 Python
利用Python将图片中扭曲矩形的复原
2020/09/07 Python
详解基于python的全局与局部序列比对的实现(DNA)
2020/10/07 Python
如何使用canvas绘制可移动网格的示例代码
2020/12/14 HTML / CSS
工商管理专业应届生求职信
2013/11/04 职场文书
公司年会抽奖活动主持词
2014/03/31 职场文书
中班上学期幼儿评语
2014/04/30 职场文书
2014年惩防体系建设工作总结
2014/12/01 职场文书
幼儿园圣诞节活动总结
2015/05/06 职场文书
体育教师教学随笔
2015/08/15 职场文书
Redis 常见使用场景
2021/08/30 Redis
JS数组去重详情
2021/11/07 Javascript