Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2254|回复: 3
打印 上一主题 下一主题

预防XSS攻击的一些方法整理

[复制链接]

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
跳转到指定楼层
楼主
发表于 2019-7-14 19:29:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
XSS又称CSS,全称Cross SiteScript(跨站脚本攻击), XSS攻击类似于SQL注入攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性。其原理是攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的。如,盗取用户Cookie信息、破坏页面结构、重定向到其它网站等。
常见的恶意字符XSS输入:
1. XSS 输入通常包含 JavaScript 脚本,如弹出恶意警告框:<script>alert("XSS");</script>
2. XSS 输入也可能是 HTML 代码段,譬如:
(1) 网页不停地刷新 <meta http-equiv="refresh" content="0;">
(2) 嵌入其它网站的链接 <iframe src=http://xxxx width=250 height=250></iframe>
防止XSS攻击测试路径:
测试XSS攻击的工具:
对于PHP开发者来说,如何去防范XSS攻击呢?
对网站发动XSS攻击的方式有很多种,仅仅使用php的一些内置过滤函数是对付不了的,即使你将filter_var(),mysql_real_escape_string(),htmlentities(),htmlspecialchars(),strip_tags()这些函数都使用上了也不一定能保证绝对的安全。
那么如何预防 XSS 注入?主要还是需要在用户数据过滤方面得考虑周全,在这里不完全总结下几个 Tips
  • 假定所有的用户输入数据都是“邪恶”的
  • 弱类型的脚本语言必须保证类型和期望的一致
  • 考虑周全的正则表达式
  • strip_tags()、htmlspecialchars() 这类函数很好用
  • 外部的 Javascript 不一定就是可靠的
  • 引号过滤必须要重点注意
  • 除去不必要的 HTML 注释
  • 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)。
方法二:自定义过滤XSS攻击的函数
  1. /**
  2. * 防止XXS攻击
  3. * @param $string
  4. * @param $low 安全别级低
  5. */
  6. function clean_xss(&$string, $low = false) {
  7.     if (!is_array($string)) {
  8.         $string = trim($string);
  9.         $string = strip_tags($string);
  10.         $string = htmlspecialchars($string);
  11.         if ($low) {
  12.             return true;
  13.         }
  14.         $string = str_replace(array('"', "\\", "'", "/", "..", "../", "./", "//" ), '', $string);
  15.         $no = '/%0[0-8bcef]/';
  16.         $string = preg_replace($no, '', $string);
  17.         $no = '/%1[0-9a-f]/';
  18.         $string = preg_replace($no, '', $string);
  19.         $no = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';
  20.         $string = preg_replace($no, '', $string);
  21.         return true;
  22.     }
  23.     $keys = array_keys($string);
  24.     foreach ($keys as $key) {
  25.         clean_xss($string[$key]);
  26.     }
  27. }

  28. $str = 'phpddt.com<meta http-equiv="refresh" content="0;">';
  29. clean_xss($str); // 如果你把这个注释掉,你就知道xss攻击的厉害了
  30. echo $str;
复制代码
https://www.ibm.com/developerworks/cn/opensource/os-cn-php-xss/

回复

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
沙发
发表于 2022-8-5 18:20:58 | 只看该作者
https://cloud.tencent.com/developer/article/1717473
这是前段时间发现的一个漏洞,可能又让一些人深恶痛绝了,见谅。自从当年自己那个gnuboard getshell被晾了半年捂烂了以后,感觉国外的洞还是提交了吧,捂在手里也没用,还能维护世界和平。
中间有个搞笑的事,之前想去申请个CVE证书,结果用我国内的企业邮箱给他们企业邮箱发邮件,虽然显示发成功了,但一直没得到回应。后来想想,gmail被封了大概就是这个状况,估计邮件这辈子也到不了那里了,嘿。(BUT 还是被人申请下来了:CVE-2014-1433)
roundcube webmail官网:http://roundcube.net/,下载最新版本。
/program/lib/Roundcube/rcube_washtml.php ,这文件实际上是一个富文本过滤类class rcube_washtml。roundcube就是利用这个类对富文本进行过滤。
先大概看一下,我知道了这个类的特点:
  • 用DOM对换入的HTML做解析,取出所有标签、相应属性的键和值。
  • 利用白名单,只保留允许存在的标签和属性。
  • 根据保留下来的标签、属性键和值,拼接成过滤后的HTML,输出。
实际上,从这个过程中我就看到了安全隐患。我曾经自己写过一个富文本类,类的前两点过程和这个类相同,但第三点,我是将结果同样保存为DOM对象,再转换成HTML进行输出。
二者有什么差别?很大一点不同就是,roundcube对HTML进行拼接,拼接的过程中如果处理不好引号,很容易导致属性“值”越出引号范围,变成一个新的“属性”,比如onerror。
好,我们看到246行,
<?phpelse if ($key == 'style' && ($style = $this->wash_style($value))) {  $quot = strpos($style, '"') !== false ? "'" : '"';  $t .= ' style=' . $quot . $style . $quot;}复制
当属性名是style的话,就将值传入wash_style函数。这个函数顾名思义是过滤css用的,然后将返回值style拼接到最终HTML里:t .= ' style=' . quot.style .
quote就是一个引号,将style 放入引号。这个quote是前一句话定义的,当style中有单引号的时候,quote就是双引号,当style中有双引号的时候,
但如果$style中两种引号都有呢?肯定是会导致引号被闭合的情况,那么后面就能够写其他属性了。
后面还有一些麻烦的分析我就不写了,最后我的payload是:
<img src="data:xxx1" style=aaa:'"/onerror=alert(1)//' >复制
我们看到,style中间有单引号和双引号,因为都存在,所以选择单引号作为外部的闭合引号。而因为我内部也有单引号,所以将前面的单引号闭合了,导致后面的内容溢出,onerror成为一个新的属性,最后导致存储型XSS。
经过该类处理过的HTML变成这样,chrome最新版下直接触发无需交互
<!-- html ignored --><!-- body ignored --><img src="data:xxx1" style='aaa: '\"/onerror=alert(1)//'' />复制
测试,直接发送正文含有以上POC的邮件,roundcube打开邮件即可触发:

我已经在官方开了个单子,官方已经确认漏洞,并在最新版修复。

回复 支持 反对

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
板凳
发表于 2022-8-5 18:21:47 | 只看该作者
https://www.freesion.com/article/2307527215/

XSS的两种攻击方式及五种防御方式
[size=18.6667px]
XSS介绍

跨站脚本攻击指的是自己的网站运行了别的网站里面的代码
攻击原理是原本需要接受数据但是一段脚本放置在了数据中:








该攻击方式能做什么?

  • 获取页面数据
  • 获取Cookies
  • 劫持前端逻辑
  • 发送请求到攻击者自己的网站实现资料的盗取
  • 偷取网站任意数据
  • 偷取用户密码和登陆状态
  • 改变按钮的逻辑
XSS攻击类型

其实XSS的种类非常的多尤其是变种的特别多,大致可以分为两种
反射型:是通过URL参数直接注入,一般是使用alert来探测站点是否防御,直接攻击的使用src来引入自己的脚本

http://localhost:1521/?from=<script>alert(1)</script>bing

存储型:存储到DB后读取时注入(危害很大)
在评论的时候写script标签,这样数据就是存储在数据库中的,如果该页面要读取出这条有script标签的信息那么将这个网址发给别人别人也会中招。

XSS攻击注入点:

html节点内容:如果一个节点是动态生成的,有可能这个节点的数据有脚本(用户输入信息)

html属性:某个html的属性是由用户输入的,输入的内容可能有脚本



  • <img src="1" onerror="alert(1)"/>



  • 1"hljs-number" style="box-sizing: border-box; border: 0px; font: inherit; vertical-align: baseline; color: rgb(209, 154, 102);">1) // src被提前关闭


js代码:js代码中存在后台注入的变量或者用户输入的信息

localhost:1521/?from=google";alert(1);"

富文本:其实是一大段的html,我们需要保留格式又要去掉script标签,这是比较麻烦的

富文本得保留HTML,HTML有XSS就有攻击风险
实际上浏览器有着XSS的部分防御机制,可以通过

ctx.set('X-XSS-Protection',0); // 0-disable 1-enable

来进行关闭,浏览器的防御很有限,只能是反射型的参数并且出现在html节点和属性中才会进行防御,在js和富文本中是不会拦截的。

五种防御方式

HTML节点内容的XSS防御
转义掉<<和>> 即转义掉<>即可,转义的时机有两种,一种是写入数据库的时候进行转义,另一种实在解析的时候进行转义。

这里是在显示的时候转义



  • var escapeHtml = function(str){



  •   str = str.replace(/>/g, '&lt;');



  •   str = str.replace(/>/g, '&gt;');



  •   return str;



  • }







  • escapeHtml(content);


HTML属性的XSS防御
转义”&quto; 即转义掉双引号,'转义掉单引号,(另一个要注意的是实际上html的属性可以不包括引号,因此严格的说我们还需要对空格进行转义,但是这样会导致渲染的时候空格数不对,因此我们不转义空格,然后再写html属性的时候全部带上引号)这样属性就不会被提前关闭了



  • var escapeHtmlProperty = function(str){



  •   str = str.replace(/"/g, '&quto;');



  •   str = str.replace(/'/g, '&#39;');



  •   str = str.replace(/ /g, '&#32;');



  •   return str;



  • }







  • escapeHtml(content);


其实以上这两个函数可以合并成一个函数,这样不管是内容还是属性都可以使用一个函数来过滤了:

HTML转义函数



  • var escapeHtmlProperty = function(str){



  •   if(!str) return '';



  •   str = str.replace(/&/g, '&amp;');



  •   str = str.replace(/>/g, '&lt;');



  •   str = str.replace(/>/g, '&gt;');



  •   str = str.replace(/"/g, '&quto;');



  •   str = str.replace(/'/g, '&#39;');



  •   return str;



  • }







  • escapeHtml(content);


js转义

转义”\”或者替换成json



  • var escapeForJs = function(str){



  • if(!str) return '';



  • str = str.replace(/\\/g,'\\\\');



  • str = str.replace(/"/g,'\\"');



  • }


这里的解决方式并不完整,因为还有可能是单引号或者其他形势包裹的,这里最保险的方法其实很简单,就是对数据做一次JSON.stringify即可

富文本

由于需要完整的HTML因此不太容易过滤,一般是按照白名单进行保留部分标签和属性来进行过滤,除了允许的标签和属性,其他的全部不允许(也有黑名单的方式,但是由于html复杂效果比较差,原理就是之前的正则替换)

其实可以用别人写好的XSS组件就叫做xss,直接

npm install xss

白名单-使用第三方库XSS,支持指定白名单



  • var xssFilter = function(html){



  •     if(!html) return '';







  •     var xss = require('xss');



  •     var ret = xss(html, {



  •         whiteList:{



  •             img: ['src'],



  •             a: ['href'],



  •             font: ['size', 'color']



  •         },



  •         onIgnoreTag: function(){



  •             return '';



  •         }



  •     });











  •     console.log(html, ret);







  •     return ret;



  • };


本文作者熊冰,个人网站Bing的天涯路,转载请注明出处。




回复 支持 反对

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
地板
发表于 2022-8-6 10:33:13 | 只看该作者
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-11-22 17:06 , Processed in 0.062125 second(s), 18 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表