整理php防注入和XSS攻击通用过滤


Posted in PHP onSeptember 13, 2015

对网站发动XSS攻击的方式有很多种,仅仅使用php的一些内置过滤函数是对付不了的,即使你将filter_var,mysql_real_escape_string,htmlentities,htmlspecialchars,strip_tags这些函数都使用上了也不一定能保证绝对的安全。

那么如何预防 XSS 注入?主要还是需要在用户数据过滤方面得考虑周全,在这里不完全总结下几个 Tips

1. 假定所有的用户输入数据都是“邪恶”的
2. 弱类型的脚本语言必须保证类型和期望的一致
3. 考虑周全的正则表达式
4. strip_tags、htmlspecialchars 这类函数很好用
5. 外部的 Javascript 不一定就是可靠的
6. 引号过滤必须要重点注意
7. 除去不必要的 HTML 注释
8. Exploer 求你放过我吧……

方法一,利用php htmlentities函数

例子

php防止XSS跨站脚本攻击的方法:是针对非法的HTML代码包括单双引号等,使用htmlspecialchars()函数 。
在使用htmlspecialchars()函数的时候注意第二个参数, 直接用htmlspecialchars($string) 的话,第二个参数默认是ENT_COMPAT,函数默认只是转化双引号(“), 不对单引号(‘)做转义.

所以,htmlspecialchars函数更多的时候要加上第二个参数, 应该这样用: htmlspecialchars($string,ENT_QUOTES).当然,如果需要不转化如何的引号,用htmlspecialchars($string,ENT_NOQUOTES).
另外, 尽量少用htmlentities, 在全部英文的时候htmlentities和htmlspecialchars没有区别,都可以达到目的.但是,中文情况下, htmlentities却会转化所有的html代码,连同里面的它无法识别的中文字符也给转化了。
htmlentities和htmlspecialchars这两个函数对 '之类的字符串支持不好,都不能转化, 所以用htmlentities和htmlspecialchars转化的字符串只能防止XSS攻击,不能防止SQL注入攻击.

所有有打印的语句如echo,print等 在打印前都要使用htmlentities() 进行过滤,这样可以防止Xss,注意中文要写出htmlentities($name,ENT_NOQUOTES,GB2312) 。

方法二,什么也不多说我们给一个函数

例子

function xss_clean($data){
 // Fix &entity\n;
 $data=str_replace(array('&','<','>'),array('&amp;','&lt;','&gt;'),$data);
 $data=preg_replace('/(&#*\w+)[\x00-\x20]+;/u','$1;',$data);
 $data=preg_replace('/(&#x*[0-9A-F]+);*/iu','$1;',$data);
 $data=html_entity_decode($data,ENT_COMPAT,'UTF-8');
 // Remove any attribute starting with "on" or xmlns
 $data=preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu','$1>',$data);
 // Remove javascript: and vbscript: protocols
 $data=preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu','$1=$2nojavascript...',$data);
 $data=preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu','$1=$2novbscript...',$data);
 $data=preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u','$1=$2nomozbinding...',$data);
 // Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
 $data=preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i','$1>',$data);
 $data=preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i','$1>',$data);
 $data=preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu','$1>',$data);
 // Remove namespaced elements (we do not need them)
 $data=preg_replace('#</*\w+:\w[^>]*+>#i','',$data);
 do{// Remove really unwanted tags
 $old_data=$data;
 $data=preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i','',$data);
 }while($old_data!==$data);
 // we are done...
 return $data;
}

方法三:

<?php
//php防注入和XSS攻击通用过滤. 
//by qq:831937
$_GET     && SafeFilter($_GET);
$_POST    && SafeFilter($_POST);
$_COOKIE  && SafeFilter($_COOKIE);
 
function SafeFilter (&$arr) 
{
    
   $ra=Array('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/','/script/','/javascript/','/vbscript/','/expression/','/applet/','/meta/','/xml/','/blink/','/link/','/style/','/embed/','/object/','/frame/','/layer/','/title/','/bgsound/','/base/','/onload/','/onunload/','/onchange/','/onsubmit/','/onreset/','/onselect/','/onblur/','/onfocus/','/onabort/','/onkeydown/','/onkeypress/','/onkeyup/','/onclick/','/ondblclick/','/onmousedown/','/onmousemove/','/onmouseout/','/onmouseover/','/onmouseup/','/onunload/');
    
   if (is_array($arr))
   {
     foreach ($arr as $key => $value) 
     {
        if (!is_array($value))
        {
          if (!get_magic_quotes_gpc())             //不对magic_quotes_gpc转义过的字符使用addslashes(),避免双重转义。
          {
             $value  = addslashes($value);           //给单引号(')、双引号(")、反斜线(\)与 NUL(NULL 字符)加上反斜线转义
          }
          $value       = preg_replace($ra,'',$value);     //删除非打印字符,粗暴式过滤xss可疑字符串
          $arr[$key]     = htmlentities(strip_tags($value)); //去除 HTML 和 PHP 标记并转换为 HTML 实体
        }
        else
        {
          SafeFilter($arr[$key]);
        }
     }
   }
}
?>
PHP 相关文章推荐
推荐个功能齐全的发送PHP邮件类
Jan 03 PHP
Discuz! Passport 通行证整合
Mar 27 PHP
PHP strtr() 函数使用说明
Nov 21 PHP
PHP Memcached应用实现代码
Feb 08 PHP
遍历指定目录下的所有目录和文件的php代码
Nov 27 PHP
php 解决旧系统 查出所有数据分页的类
Aug 27 PHP
PHP编码转换函数 自动转换字符集支持数组转换
Dec 16 PHP
WordPress中缩略图的使用以及相关技巧
Nov 24 PHP
[原创]php正则删除html代码中class样式属性的方法
May 24 PHP
laravel通过创建自定义artisan make命令来新建类文件详解
Aug 17 PHP
Laravel使用swoole实现websocket主动消息推送的方法介绍
Oct 20 PHP
php使用自带dom扩展进行元素匹配的原理解析
May 29 PHP
教你识别简单的免查杀PHP后门
Sep 13 #PHP
php文件扩展名判断及获取文件扩展名的N种方法
Sep 12 #PHP
php上传功能集后缀名判断和随机命名(强力推荐)
Sep 10 #PHP
ubuntu下配置nginx+php+mysql详解
Sep 10 #PHP
ThinkPHP函数详解之M方法和R方法
Sep 10 #PHP
基于JQuery+PHP编写砸金蛋中奖程序
Sep 08 #PHP
四个常见html网页乱码问题及解决办法
Sep 08 #PHP
You might like
为PHP5.4开启Zend OPCode缓存
2014/12/26 PHP
php实现监控varnish缓存服务器的状态
2014/12/30 PHP
smarty模板引擎之配置文件数据和保留数据
2015/03/30 PHP
CI框架常用经典操作类总结(路由,伪静态,分页,session,验证码等)
2016/11/21 PHP
laravel框架语言包拓展实现方法分析
2019/11/22 PHP
jquery 查找select ,并触发事件的实现代码
2011/03/30 Javascript
javascript重复绑定事件造成的后果说明
2013/03/02 Javascript
Ext中下拉列表ComboBox组件store数据格式用法介绍
2013/07/15 Javascript
js实现图片点击左右轮播
2015/07/08 Javascript
javascript巧用eval函数组装表单输入项为json对象的方法
2015/11/25 Javascript
详解Bootstrap创建表单的三种格式(一)
2016/01/04 Javascript
async/await与promise(nodejs中的异步操作问题)
2017/03/03 NodeJs
Angularjs 手写日历的实现代码(不用插件)
2017/10/18 Javascript
JS实现table表格固定表头且表头随横向滚动而滚动
2017/10/26 Javascript
vue.js默认路由不加载linkActiveClass问题的解决方法
2017/12/11 Javascript
小试小程序云开发(小结)
2019/06/06 Javascript
node.js 微信开发之定时获取access_token
2020/02/07 Javascript
js实现拖拽与碰撞检测
2020/09/18 Javascript
[03:14]辉夜杯主赛事 12月25日每日之星
2015/12/26 DOTA
Python 过滤字符串的技巧,map与itertools.imap
2008/09/06 Python
python之模拟鼠标键盘动作具体实现
2013/12/30 Python
Python MD5加密实例详解
2017/08/02 Python
pandas获取groupby分组里最大值所在的行方法
2018/04/20 Python
Python使用Matplotlib模块时坐标轴标题中文及各种特殊符号显示方法
2018/05/04 Python
python实现单链表的方法示例
2019/09/03 Python
Python socket连接中的粘包、精确传输问题实例分析
2020/03/24 Python
Python使用configparser读取ini配置文件
2020/05/25 Python
python实现AHP算法的方法实例(层次分析法)
2020/09/09 Python
python基于win32api实现键盘输入
2020/12/09 Python
迪拜航空官方网站:flydubai
2017/04/20 全球购物
HomeAway的巴西品牌:Alugue Temporada
2018/04/10 全球购物
求∏的近似值,直到最后一项的绝对值小于指定的数
2016/02/12 面试题
WEB控件可以激发服务端事件,请谈谈服务端事件是怎么发生并解释其原理?自动传回是什么?为什么要使用自动传回?
2012/02/21 面试题
大学生演讲稿范文
2014/01/11 职场文书
鼓励运动员的广播稿
2014/02/08 职场文书
个人借条范本
2015/05/25 职场文书