整理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+JS+rsa数据加密传输实现代码
Mar 23 PHP
PHP性能优化工具篇Benchmark类调试执行时间
Dec 06 PHP
PHP引用符&amp;的用法详细解析
Aug 22 PHP
XAMPP安装与使用方法详细解析
Nov 27 PHP
ThinkPHP3.1新特性之动态设置自动完成及自动验证示例代码
Jun 23 PHP
php检查字符串中是否有外链的方法
Jul 29 PHP
[原创]ThinkPHP中SHOW_RUN_TIME不能正常显示运行时间的解决方法
Oct 10 PHP
PHP实现移除数组中为空或为某值元素的方法
Jan 07 PHP
php封装json通信接口详解及实例
Mar 07 PHP
详谈phpAdmin修改密码后拒绝访问的问题
Apr 03 PHP
PHP工厂模式、单例模式与注册树模式实例详解
Jun 03 PHP
解析laravel使用workerman用户交互、服务器交互
Apr 28 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
Zerg建筑一览
2020/03/14 星际争霸
用缓存实现静态页面的测试
2006/12/06 PHP
PHP反转字符串函数strrev()函数的用法
2012/02/04 PHP
php&amp;mysql 日期操作小记
2012/02/27 PHP
Yii2 rbac权限控制之菜单menu实例教程
2016/04/28 PHP
PHP MySql增删改查的简单实例
2016/06/21 PHP
PHP数据库操作三:redis用法分析
2017/08/16 PHP
Laravel学习教程之View模块详解
2017/09/18 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
php微信公众号开发之关键词回复
2018/10/20 PHP
jQuery 学习第六课 实现一个Ajax的TreeView
2010/05/17 Javascript
Javascript setInterval的两种调用方法(实例讲解)
2013/11/29 Javascript
jquery实现点击其他区域时隐藏下拉div和遮罩层的方法
2015/12/23 Javascript
javascript 用函数实现继承详解
2016/05/28 Javascript
分享一个插件实现水珠自动下落效果
2016/06/01 Javascript
JavaScript必知必会(十) call apply bind的用法说明
2016/06/08 Javascript
微信小程序 label 组件详解及简单实例
2017/01/10 Javascript
React性能优化系列之减少props改变的实现方法
2019/01/17 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
vue 导航内容设置选中状态样式的例子
2019/11/01 Javascript
Vue使用富文本编辑器Vue-Quill-Editor(含图片自定义上传服务、清除复制粘贴样式等)
2020/05/15 Javascript
jQuery--遍历操作实例小结【后代、同胞及过滤】
2020/05/22 jQuery
vue3为什么要用proxy替代defineProperty
2020/10/19 Javascript
[04:44]显微镜下的DOTA2第二期——你所没有注意到的细节
2014/06/20 DOTA
python中的五种异常处理机制介绍
2014/09/02 Python
跟老齐学Python之做一个小游戏
2014/09/28 Python
Python实现简单的语音识别系统
2017/12/13 Python
详解python中@的用法
2019/03/27 Python
Python 实现毫秒级淘宝抢购脚本的示例代码
2019/09/16 Python
Python文件操作函数用法实例详解
2019/12/24 Python
Python 跨.py文件调用自定义函数说明
2020/06/01 Python
全球精选男装和家居用品:Article
2020/04/13 全球购物
西式婚礼证婚词
2014/01/12 职场文书
党员学习正风肃纪思想汇报
2014/09/12 职场文书
仓管员岗位职责
2015/02/03 职场文书
Go Gin实现文件上传下载的示例代码
2021/04/02 Golang