当前位置: 首页 > 图文教程 > 网络编程 > PHP > 用PHP编程防范XSS跨站脚本攻击

PHP
PHP 柱状图实现代码
PHP 用数组降低程序的时间复杂度
PHP 读取文件内容代码(txt,js等)
Php 构造函数construct的前下划线是双的_
PHP 采集程序中常用的函数
一个比较简单的PHP 分页分组类
php下图片文字混合水印与缩略图实现代码
php5 图片验证码实现代码
phpmyadmin导入(import)文件限制的解决办法
php smarty模版引擎中变量操作符及使用方法
Php Mssql操作简单封装支持存储过程
php实现的仿阿里巴巴实现同类产品翻页
php入门教程 精简版
将文件夹压缩成zip文件的php代码
PHP开发过程中常用函数收藏
php csv操作类代码
php遍历目录viewDir函数
PHP 基本语法格式
php生成xml简单实例代码
PHP下编码转换函数mb_convert_encoding与iconv的使用说明

用PHP编程防范XSS跨站脚本攻击


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 39 ::
收藏到网摘: n/a

转自:http://www.webdn.com/web_file/program/php/0602080321/

【摘 要】今天偶然看到PHP5的一个XSS漏洞,在此小结一下。顺便提醒,使用PHP5的朋友最好打下补丁,或者升级一下。

 

国内不少论坛都存在跨站脚本漏洞,国外也很多这样的例子,甚至Google也出现过,不过在12月初时修正了。(编者注:关于跨站脚本漏洞攻击,读者可参阅《详解XSS跨站脚本攻击》)。跨站攻击很容易就可以构造,而且非常隐蔽,不易被查觉(通常盗取信息后马上跳转回原页面)。

  如何攻击,在此不作说明(也不要问我),主要谈谈如何防范。首先,跨站脚本攻击都是由于对用户的输入没有进行严格的过滤造成的,所以我们必须在所有数据进入我们的网站和数据库之前把可能的危险拦截。针对非法的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=&#X40&#X61&#X76&#X61&#X73&#X63&#X72&#X69&#X70&#X74&#X3A&#X61&
    _#X6C&#X65&#X72&#X74&#X28&#X27&#X58&#X53&#X53&#X27&#X29>
 $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

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