整理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+mysql一个名片库程序
Oct 09 PHP
excellent!――ASCII Art(由目标图象生成ascii)
Feb 20 PHP
php 常用字符串函数总结
Mar 15 PHP
用php+javascript实现二级级联菜单的制作
May 06 PHP
discuz Passport 通行证 整合笔记
Jun 30 PHP
从零开始学YII2框架(六)高级应用程序模板
Aug 20 PHP
ThinkPHP的MVC开发机制实例解析
Aug 23 PHP
分享一段PHP制作的中文拼音首字母工具类
Dec 11 PHP
PHP输出两个数字中间有多少个回文数的方法
Mar 23 PHP
PHP下载生成的csv文件及问题总结
Aug 06 PHP
PHP数据库表操作的封装类及用法实例详解
Jul 12 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之数据库操作详解及乱码解决!
2007/01/02 PHP
PHP字符串处理的10个简单方法
2010/06/30 PHP
让CodeIgniter数据库缓存自动过期的处理的方法
2014/06/12 PHP
jQuery ui 1.7更新小结
2009/08/15 Javascript
js实现addClass,removeClass,hasClass的函数代码
2011/07/13 Javascript
javascript上传图片前预览图片兼容大多数浏览器
2013/10/25 Javascript
javaScript 页面自动加载事件详解
2014/02/10 Javascript
用简洁的jQuery方法toggleClass实现隔行换色
2014/10/22 Javascript
jQuery数据缓存用法分析
2015/02/20 Javascript
浅谈JavaScript中的字符编码转换问题
2015/07/07 Javascript
利用vue.js插入dom节点的方法
2017/03/15 Javascript
vue使用v-if v-show页面闪烁,div闪现的解决方法
2018/10/12 Javascript
JS实现简单的文字无缝上下滚动功能示例
2019/06/22 Javascript
原生js+canvas实现贪吃蛇效果
2020/08/02 Javascript
python概率计算器实例分析
2015/03/25 Python
Python导入模块时遇到的错误分析
2017/08/30 Python
Python实现识别图片内容的方法分析
2018/07/11 Python
python 读取Linux服务器上的文件方法
2018/12/27 Python
Python 按字典dict的键排序,并取出相应的键值放于list中的实例
2019/02/12 Python
Linux下通过python获取本机ip方法示例
2019/09/06 Python
python实现输入的数据在地图上生成热力图效果
2019/12/06 Python
OpenCV中VideoCapture类的使用详解
2020/02/14 Python
django处理select下拉表单实例(从model到前端到post到form)
2020/03/13 Python
Python3操作读写CSV文件使用包过程解析
2020/04/10 Python
Python startswith()和endswith() 方法原理解析
2020/04/28 Python
简单了解python列表和元组的区别
2020/05/14 Python
python爬虫利器之requests库的用法(超全面的爬取网页案例)
2020/12/17 Python
利用css3画个同心圆示例代码
2017/07/03 HTML / CSS
南京软件公司的.net程序员笔试题
2014/08/31 面试题
物流创业计划书
2014/02/01 职场文书
区级文明单位申报材料
2014/05/15 职场文书
劳动者解除劳动合同通知书
2015/04/16 职场文书
php随机生成验证码,php随机生成数字,php随机生成数字加字母!
2021/04/01 PHP
Python import模块的缓存问题解决方案
2021/06/02 Python
python图像处理基本操作总结(PIL库、Matplotlib及Numpy)
2021/06/08 Python
JavaScript中时间格式化新思路toLocaleString()
2021/11/07 Javascript