XSS的分类
优秀的博客:美团前端xss
XSS(跨站脚本攻击):通常指黑客通过“HTML注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。
提取用户提交的输入并将其插入到服务器响应的HTML中,这是XSS的一个明显特征
如果应用程序没有实施过滤和净化,那么久很容易受到攻击
XSS可分为三种类型
- 反射型XSS
- 存储型XSS
- 基于DOM的XSS漏洞
反射型 XSS
反射型XSS只是简单的把用户的输入的数据“反射”给浏览器。
黑客需要诱使用户“点击”一个恶意的链接,才能成功。
例子:
后台脚本:
<?php
$input=$_GET["param"];
echo "<div>".$input."</div>";
?>
用户向param提交的参数会显示在页面中
http://www.a.com/test.php?param=test
页面源代码中:
<div>test</div>
攻击方法:
http://www.a.com/test.php?param=<script>alert(xss)</script>
导致alert(xss)在页面执行
存储型XSS
讲用户输入的数据存储在服务端。常见的场景为黑客写下一篇包含恶意javascript代码的博客文章,文章发表后,所有访问该博客文章的用户,都会在他们的浏览器中执行这段恶意的Javascript代码
DOM型XSS
改变原网页dom结构的攻击
dom型xss的 变量的处理在Javascript中,存储型和反射型变量的处理都在后端代码中
比如:变量在script脚本的函数中,html又调用了这个函数。
XSS漏洞利用
- 窃取Cookie信息,造成会话劫持
- 构造GET和POST请求,如get执行删除操作,gost,构造form表单或者通过XMLHttpRequest
- XSS钓鱼,利用JavaScript在页面上画一个伪造的登录框
- 识别用户的浏览器版本,通过UserAgent
- 识别用户安全的软件,classid,通过软件漏洞,进行攻击
- 识别用户访问过的网站; 利用CSS中的style的visited属性
- 获取用户真实的ip
- XSS攻击平台:AttactAPI
- XSS Worm :存储型Xss发起
XSS漏洞检测
- 利用字符编码
要求数据库,web服务器,系统,使用相同的字符编码,一般为UTF-8
服务器使用GB2312编码,浏览器使用utf-8编码。导致后台的“\”会被构造的字符吃掉变为一个新的UTF字符,导致注释失效 - 绕过长度限制
- 使用
<base>
标签
XSS漏洞防御
- HttpOnly:对于Cookie标记HttpOnly信息
浏览器禁止页面的JavaSprit访问带有HttpOnly的Cookie信息。HttpOnly并非针对XSS漏洞,只是防止XSS漏洞造成的会话攻击
XSS攻击不光是Cookie劫持问题,还有窃取用户信息,模拟用户身份执行操作等严重后果
-
输入检查
常见的web漏洞注入类问题,都要求攻击者构造一些特殊字符,这些特殊字符是正常用户用不到的,所以输入检查就有必要了
输入检查的逻辑,必须放在服务器端代码中实现,一般考虑到性能的要求是浏览器和服务器中双实现
1.白名单的思想,被用户白名单的检查,如邮件,电话等格式
2.检查用户输入数据中包含的特殊字符,如`“<” “>” “、”等
3.XSS Filter:比较智能的“输入检查”,可能匹配XSS特征。
比如查找用户数据中是否包含了“<script>”、“javascript”等敏感字符
XSS Filter在用户提交数据时获取变量,并进行检查;但此时用户数据并
没有结合渲染页面的HTML代码,因此XSS Filter对于语境的理解并不完整
- 输出检查
一般来说,除了富文本的输出外,在变量输出到HTML页面时,可以采用编码或者转义的方式防御XSS
安全的编码函数
- HtmlEncode:针对HTML代码的编码方式
- JavascriptEncode:Jacascrpt的编码方式
- PHP-----htmlentitles()和htmlspecialchars()两个函数
- XMLEcode(其实现与HtmlEncode类似);JSONEncode(与JavascriptEncode累次)
HtmlEncode
HtmlEncode是一种函数实现,他的作用是讲字符转换为HTMLEntities,对应的标准为ISO-8859-1
为对抗XSS,在HTMLEncode中要求至少转换一下字符
& -->;<–>;>–>;"–>;’–>;/ -->
Javascript
1.JavaScript与htmlencode方式不同,他需要使用“\”对特使字符进行转义
2.要求输出的变量必须在引号的内部
例如:var y = '"'+escapeJavascipt($evil) + '"'
攻击者想要逃逸出信号的范围,会有困难
在正确的地方使用正确的编码方式
变量被填充入HTML代码中,存在以下场景
- 在HTML标签中输出;使用HtmlEncode编码
代码:
<div>$var<div>
<a href = # >$var</a>
一般利用方式构造<Scritp>
标签,例如:<script>alert(/ xss)<script>
<div><script>alert(/ xss)<script>< /div>
- 在Html属性中输出,使用HtmlEcode编码
<div id="abc" name="$var" ></div>
攻击方法 "><script>alert(/xss)</script><"
<div id="abc" name=""><script>alert(/xss)</script><"" ></div>
- 在
<Script>
标签中输出 ,使用JavaScriptEncode
<script>
var x = "$var";
</script>
攻击方法,先闭合引号在实施XSS:";alert(/xss/);//
<script>
var x = "";alert(/xss/);//";
</script>
- 在事件中输出,使用JavaScriptEncode
<a href=# onclick="funcA('$var')" >test</a>
攻击方法:');alert(xss);//
<a href=# onclick="funcA('');alert(xss);//')" >test</a>
- 在地址中输出,使用URLEncode
在地址中输出较为复杂,一般来说,在URL的path或者search中输出;使用URLEncode。讲字符串转换为“%HH”的形式,如空格就是“%20”,<就是“%3c”
处理富文本
使用输入检查的思路,使用白名单,避免使用黑名单
在过滤富文本时,“事件”应该被严格禁止;一些危险的标签被禁止,如<script> 、<iframe>、<base>、<form>等
只允许一些比较安全的标签如:<a > <img> <div>
防御DOM型攻击
<script>
function test(){
var str=document.getElementById("test").value;
document.getElementById("t").innerHTML="<a href='"+str+'">testLink</a>";
}
</script>
<div id ="t"></div>
<input type="test" id="test" value="" />
<input type="button" id="s" value="write" onclick="test()"/>
在button的onclick事件中,调用了test()函数,将HTML代码写入DOM节点,最后导致了XSS的发生。test()函数中获取用户输入的变量,
变量输出在Script脚本中,最后又被.innerHTML输出到HTML页面中
下面是javascript输出到HTML页面的必经之路:
- xxx.innerHTML=
- xxx.outerHTML=
- document.write()
- document.writeIn()
防御:
首先在变量输出到Scritp中时,应该执行一次JavascritpEncode
其次在.innerHTML输出到HTML中,分情况执行HTMLEncode或者JavascritpEncode