整理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实现文件上传二法
Oct 09 PHP
php array_pop()数组函数将数组最后一个单元弹出(出栈)
Jul 12 PHP
php遍历数组的方法分享
Mar 22 PHP
解析如何在PHP下载文件名中解决乱码的问题
Jun 20 PHP
解析centos中Apache、php、mysql 默认安装路径
Jun 25 PHP
Drupal读取Excel并导入数据库实例
Mar 02 PHP
thinkPHP实现瀑布流的方法
Nov 29 PHP
php简单判断文本编码的方法
Jul 30 PHP
php实现图片上传、剪切功能
May 07 PHP
php实现产品加入购物车功能(1)
Jul 23 PHP
PHP中in_array的隐式转换的解决方法
Mar 06 PHP
PHP For循环字母A-Z当超过26个字母时输出AA,AB,AC
Feb 16 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
codeigniter教程之多文件上传使用示例
2014/02/11 PHP
PHP+Mysql实现多关键字与多字段生成SQL语句的函数
2014/11/05 PHP
jQuery 事件队列调整方法
2009/09/18 Javascript
基于jquery+thickbox仿校内登录注册框
2010/06/07 Javascript
Javascript冒泡排序算法详解
2014/12/03 Javascript
js实现网页抽奖实例
2015/08/05 Javascript
jQuery实现布局高宽自适应的简单实例
2016/05/28 Javascript
第一篇初识bootstrap
2016/06/21 Javascript
jquery把int类型转换成字符串类型的方法
2016/10/07 Javascript
原生JS实现图片轮播效果
2016/12/26 Javascript
angularjs ocLazyLoad分步加载js文件实例
2017/01/17 Javascript
JSON 数据详解及实例代码分析
2017/01/20 Javascript
使用vue制作FullPage页面滚动效果
2017/08/21 Javascript
node.js利用mongoose获取mongodb数据的格式化问题详解
2017/10/06 Javascript
JS实现的JSON数组去重算法示例
2018/04/11 Javascript
nodejs 使用nodejs-websocket模块实现点对点实时通讯
2018/11/28 NodeJs
jQuery实现的简单日历组件定义与用法示例
2018/12/24 jQuery
seajs和requirejs模块化简单案例分析
2019/08/26 Javascript
深入浅出vue图片路径的实现
2019/09/04 Javascript
微信小程序tabBar设置实例解析
2019/11/14 Javascript
微信小程序实现拨打电话功能的示例代码
2020/06/28 Javascript
基于javascript的无缝滚动动画1
2020/08/07 Javascript
[46:21]Liquid vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.23
2018/08/24 DOTA
跟老齐学Python之网站的结构
2014/10/24 Python
python轻松查到删除自己的微信好友
2016/01/10 Python
python绘制条形图方法代码详解
2017/12/19 Python
Python爬虫实现全国失信被执行人名单查询功能示例
2018/05/03 Python
深入浅析Python的类
2018/06/22 Python
解决pandas .to_excel不覆盖已有sheet的问题
2018/12/10 Python
python 爬取英雄联盟皮肤并下载的示例
2020/12/04 Python
Perry Ellis官网:美国男士品味服装
2016/12/09 全球购物
泰国折扣酒店预订:Hotels2Thailand
2018/03/20 全球购物
捷克建筑材料网上商店:DEK.cz
2021/03/06 全球购物
团员年度个人总结
2015/02/26 职场文书
结婚幸福感言
2015/08/01 职场文书
python自然语言处理之字典树知识总结
2021/04/25 Python