整理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 相关文章推荐
PHP5 安装方法
Jan 15 PHP
php抓取https的内容的代码
Apr 06 PHP
提高PHP编程效率的53个要点(经验小结)
Sep 04 PHP
PHP提交表单失败后如何保留已经填写的信息
Jun 20 PHP
php使用COPY函数更新配置文件的方法
Jun 18 PHP
详解WordPress中给链接添加查询字符串的方法
Dec 18 PHP
PHP 读取文本文件内容并分页显示
Jan 02 PHP
Windows2003下php5.4安装配置教程(Apache2.4)
Jun 30 PHP
PHP正则匹配反斜杠'\'和美元'$'的方法
Feb 08 PHP
PHP单例模式与工厂模式详解
Aug 29 PHP
浅析PHP中的闭包和匿名函数
Dec 25 PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
Feb 13 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
php中使用session防止用户非法登录后台的方法
2015/01/27 PHP
php根据某字段对多维数组进行排序的方法
2015/03/07 PHP
php字符串函数学习之strstr()
2015/03/27 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
php读取本地json文件的实例
2018/03/07 PHP
javascript document.images实例
2008/05/27 Javascript
利用javascript实现web页面中指定区域打印
2013/10/30 Javascript
CSS3,HTML5和jQuery搜索框集锦
2014/12/02 Javascript
JQuery插件Quicksand实现超炫的动画洗牌效果
2015/05/03 Javascript
JavaScript ES5标准中新增的Array方法
2016/06/28 Javascript
vue.js入门教程之基础语法小结
2016/09/01 Javascript
javascript cookie基础应用之记录用户名的方法
2016/09/20 Javascript
vue使用axios实现文件上传进度的实时更新详解
2017/12/20 Javascript
Angular入口组件(entry component)与声明式组件的区别详解
2018/04/09 Javascript
VUE 3D轮播图封装实现方法
2018/07/03 Javascript
js删除对象/数组中null、undefined、空对象及空数组方法示例
2018/11/14 Javascript
使用layui前端框架弹出form表单以及提交的示例
2019/10/25 Javascript
跟老齐学Python之开始真正编程
2014/09/12 Python
Python解析网页源代码中的115网盘链接实例
2014/09/30 Python
Python中模拟enum枚举类型的5种方法分享
2014/11/22 Python
初学Python函数的笔记整理
2015/04/07 Python
python清除函数占用的内存方法
2018/06/25 Python
python 限制函数执行时间,自己实现timeout的实例
2019/01/12 Python
浅谈pytorch中的BN层的注意事项
2020/06/23 Python
python简单利用字典破解zip文件口令
2020/09/07 Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
2020/11/27 Python
HTML5中input[type='date']自定义样式与日历校验功能的实现代码
2017/07/11 HTML / CSS
详解Canvas实用库Fabric.js使用手册
2019/01/07 HTML / CSS
Otel.com:折扣酒店预订
2017/08/24 全球购物
美国基督教约会网站:ChristianCafe.com
2020/02/04 全球购物
2015年“公民道德宣传日”活动方案
2015/05/06 职场文书
微观世界观后感
2015/06/10 职场文书
公司车辆维修管理制度
2015/08/05 职场文书
教师纪律作风整顿心得体会
2016/01/23 职场文书
Vue.Draggable实现交换位置
2022/04/07 Vue.js
Spring Cloud OpenFeign模版化客户端
2022/06/25 Java/Android