XSS防御
更新日期:
XSS的本质是一种“HTML 注入”, 用户的数据被当成了HTML代码的一部分来执行,从而混淆了原本的语义,产生了新的语义。
分类
反射型XSS
简单地把用户输入数据“反射”给浏览器。 一般需要诱导用户点击恶意链接, 非持久化。1
2
3<?php
echo "<p>欢迎您, ".$username."!</p>";
?>如果这里的username变量,是通过获取用户输入的,
1
$username = $_GET["name"];
那么可以制造恶意链接欺骗用户点击, 触发恶意代码
1
http://localhost/test.php?name=<script>alert(/我的名字是张三/)</script>
存储型XSS
将用户输入的数据“存储”在服务器端。用户访问普通链接即可中招, 容易造成蠕虫。
如上文例子, 如果 username 已经存储于数据库,用户直接访问普通链接也会中招。1
$username = "<script>alert(/我的名字是张三/)</script>"
存储型XSS具有较强的稳定性
DOM Based XSS
通过修改页面DOM节点数据信息而形成的XSS跨站脚本攻击1
2
3
4
5
6
7
8
9
10<script>
function xsstest()
{
var str = document.getElementById("input").value;
document.getElementById("output").innerHTML = "<img src='"+str+"'></img>";
}
</script>
<input type="text" id="input" size=50 value="" />
<input type="button" value="提交" onclick="xsstest()" />通过构造如下数据,输入
1
#’ onerror=’javascript:alert(/DOM Based XSS Test/)
在浏览器中提交后,代码被执行,出现了弹窗提示
DOM Based XSS 效果上来说也是反射性XSS
检测方法
通常有一些方式可以测试网站是否有正确处理特殊字符1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19><script>alert(document.cookie)</script>
='><script>alert(document.cookie)</script>
"><script>alert(document.cookie)</script>
<script>alert(document.cookie)</script>
<script>alert(vulnerable)</script>
%3Cscript%3Ealert('XSS')%3C/script%3E
<script>alert('XSS')</script>
<img src="javascript:alert('XSS')">
<img src="http://xxx.com/yyy.png" onerror="alert('XSS')">
<div style="height:expression(alert('XSS'),1)" />(这个仅限 IE 有效)
XSS防御
使用HttpOnly
- 解决 XSS 后的 Cookie 劫持攻击。
- 在支持 HttpOnly cookies 的浏览器中,JavaScript 是无法读取和修改 HttpOnly cookies。
输入检查
- 过滤特殊字符。“XSS filter”
- 不够智能,有可能过滤用户需要的数据。如: 1+1 > 2 ==> 1+1 2
输出检查
针对 HTML 代码: HtmlEncode
它的作用是将字符转换成HTMLEntities,对应的标准是ISO88591。
对了对抗XSS,在HtmlEncode中至少要转换以下字符:1
2
3
4
5
6& => &
< => <
> => >
“ => "
‘ => '
/ => /相关防御:
一般来说, 用户可控制变量输出是在 HTML 代码, 如:1
2
3
4
5<!--HTML 标签中输出-->
<div>$var</div>
<!--HTML HTML 属性中输出-->
<div name=”$var”></div>需要执行恶意代码都需要包含
<script></script>
对应这种情况 我们必须进行HtmlEncode针对 JavaScript 代码: JavaScriptEncode
与 HtmlEncode 编码方式不同, 它需要使用“\” 对特殊字符进行转义。
要求输出的变量必须包含在引号内部。 如: var y = ‘ “ ‘ + escapeJavascript($evil) + ’ ” ’相关防御:
1
2
3
4
5<!--在script标签中输出-->
<script>$var </script>
<!--在事件中输出-->
<a onclick="onclick=$var"></a>此类注入恶意代码可直接运行,需要加入JavascriptEncode, 并确保输出变量在引号中
防御 DOM Based XSS
对于浏览器来说, htmlparser 会优先于 JavaScript Parse 执行。解析过程HtmlEncode的字符先被解码,然后执行JavaScript事件。- 在 $var 输出到
<script>
时,应该执行一次 javascriptencode - 如果javascript将输出变量写入DOM时,根据上述场景进行再一次encode (HtmlEncode or JavaScriptEncode)
- 在 $var 输出到
参考
- 《白帽子讲 Web 安全》