XSS攻击

XSS攻击思路

XSS的本质还是一种”HTML“漏洞。用户的数据被当成了HTML的一部分来执行,从而混淆了原有的语义,产生了新的语义。如果未对用户的输入做任何处理,那么会直接产生XSS攻击漏洞。

通过特定标签实现攻击

在事件中输出

onclick

在URL地址中构造

将XSS攻击代码通过URLEncode进行编码,然后放在URL中实施攻击。

在地址输出中:

<a href="http://www.test.com/?test=$var">test</a>

可能的攻击方法

<a href="http://www.test.com/?test=" onclick=alert(1)"">test</a>

构造伪协议实施攻击

<a href="javascript:alert(1);">test</a>

除了javascript作为伪协议可以执行代码外,也有其他的伪协议可能导致脚本运行。

利用字符编码

var redirectUrl="";alert(/XSS/);";

"进行了转义,得到一个Unicode字符,因此,实际上得到的结果是这样的

<script>%c1";alert(/XSS/);</script>

绕过长度限制

对用户输入的内容进行长度限制,使攻击者连一个完整的函数都无法写完,XSS攻击可能无法成功。但是依然存在风险点,攻击者可以利用事件(Event)来缩短所需要的字节数。

$var输出为:"onclick=alert(1)//
<input type=text value="" "onclick=alert(1)//"/>

当用户点击文本框,alert将被执行。

但利用”事件“能够缩短的字节数是有限的,最好的办法是把XSS Payload写到别处,再通过简单的代码加载这段XSS Payload。

最常用的一个“藏代码”的地方,就是“location.hash”。而且根据HTTP协议,location.hash的内容不会在HTTP包中发送,所以服务端的web日志中并不会记录下location.hash里的内容,从而也更好地隐藏了黑客的真实意图。

$var输出为: " onclick="eval(location.hash.substr(1))

输出后的HTML是:

<input type="text" value="" onclick="eval(location.hash.substr(1))" />

因为location.hash的第一个字符是#,所以必须去除第一个字符才行。此时构造出的XSS URL为:

http://www.a.com/test.html#alert(1)

location.hash本身没有长度限制,但是浏览器的地址栏是有长度限制的,不过这个长度已经足够写很长的XSS Payload了。要是地址栏的长度也不够用, 还可以再使用

多个输入框使用注释符绕过

<base>标签

windows.name

检查

代码过滤

对于用户输入的检查的逻辑,必须放在服务端代码中实现,如果只是在客户端使用JavaScript进行输入检查,是很容易被被攻击者绕过的。目前Web开发的普遍做法,是同时在客户端JavaScript中和服务器端代码中实现相同的输入检查。客户端JavaScript的输入检查,可以阻挡大部分误操作的正常用户,从而节约服务器资源。

对输入进行特征匹配:关键字,称为XSS Filter。

javascript script base等

可以在网上找到很多关于XSS Filter的实现。

但是如果用户提交的是变量$var,就不会被过滤。但是var的内容却携带有XSS攻击脚本的话,一样会被攻击成功。

在对特殊字符处理的时候,还需要注意不要把正常的业务影响到。比如:

1+1 < 3

还有下面的情况

$nickname='hello "world"'

如果在XSS Filter中对双引号进行转义:

$nickname='hello "world"'

在JavaScript代码中展示时:

<script>
var nickname='hello "world"';
document.write(nickname)
</script>

这两段代码,得到的结果并不一样。

hello "world"
hello "world"

而第一个结果并不是用户想看到的。

安全的编码函数

针对HTML代码的编码方式是HtmlEncode,它并非专有名词,只是一种函数实现,它的作用是将字符转换成HTMLEntities,对应的标准是ISO-8859-1。

针对PHP,有htmllentities,htmlspecialchars,相应的,JavaScript的编码方式可以使用JavaScriptEncode。

在对抗XSS时,JavaScriptEncode还要求输出的变量必须在引号内部,以避免造成安全问题。

var x = escapeJavaScript($evil);

var y = '"'+ escapeJavaScript($evil) +'"';

如果escapeJavaScript函数只转义了几个危险字符,比如' " < > & #等,那么上面两行的代码输出后可能会变成:

var x = 1;alert(2);

var y = "1;alert(2)";

更严格的做法是,除了数字,字母外的所有字符,都使用十六进制'xHH'的方式进行编码。

var x = 1;alert(2);

变成了

var x = 1x3balertx282x29;

这样,也可以最大化的保证代码是安全的。

还有其他很多类似于HtmlEncode、JavaScriptEncode功能的函数。可以在适当的情况下选用适当的函数。

XSS攻击主要发生在MVC架构中的View层,大部分XSS漏洞可以在模板系统中解决。

Secure By Default

XSS是很复杂的问题,需要”在正确的地方使用正确的编码方式“。

<body>
    <a href=# onclick="alert('$var');">test</a>
</body>

如果用户输入

$var = htmlencode("');alert('2");

渲染后的结果是

<body>
    <a href=# onclick="alert('&#x27;#x29;&#x3b;alert&#x28;&#x27;2');">test</a>
</body>

对于浏览器来说,htmlparse会优先于JavaScript Parse执行,所以解析过程是,被HtmlEncode的字符先被解码,然后执行JavaScript时间:

<body>
    <a href=# onclick="alert('');alert('2')">test</a>
</body>

成功在onclick事件中注入了xss代码。

防止XSS攻击需要区分情况对待,并不是使用了某一策略就万事大吉。

处理富文本

用户发布文章、评论、图片等。

危险标签

<iframe>  <script> <base> <form>等

过滤规则应该选用白名单,避免使用黑名单,比如,只允许

<a> <img> <div>等

白名单原则不仅仅用于标签的选择,同样应该用于属性与事件的选择。

CSS处理

如果允许用户自定义CSS、style,则也可能导致XSS攻击。那么需要一个CSS Parser对样式进行分析。

CSS分析开源工具1

CSS分析开源工具2

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函数,而该函数中最关键的一句是:

document.getElementById("t").innerHTML = "<a href='"+str"'">testLink</a>

将HTML代码写入了DOM节点,导致漏洞产生。

即使通过JavaScriptEscape,也仍然可能产生漏洞。

<script>
var x="$var"
document.write("<a href='"+x+"'">testLink</a>)
</script>
<script>
var x="x20x27onclickx3dalertx28x29x3bx2fx27"
document.write("<a href='"+x+"'">testLink</a>)
</script>

在第一次执行JavaScriptEscape之后,只保护了变量x,但是当document.write输出数据到HTML页面时,浏览器重新渲染了页面。在<script>标签执行时,已经对变量进行了解码,其后document.write再运行时,参数就变成了

<a href=' ' onclick=alert(1);//''>testLink</a>

即使改成HtmlEncode依然可能产生漏洞

<script>
var x="1&#x22;&#x29;&#x3b;alert&#x28;2&#x29;&#x3b;&#x2f;&#x22"
document.write("<a href=# onclick='alert(""+x+"")'>testLink</a>)
</script>

服务器把变量HtmlEncode后再输出到<script>中,然后变量x作为onclick事件的一个函数参数被document.write到了HTML页面里。onclick事件执行了两次alert,第二次是被XSS注入的。

其他有可能导致XSS攻击的函数

.after()
.append()
.appendTo()
.before()
.html()
.insertAfter()
.insertBefore()
.prepend()
.prependTo()
.replaceAll()
.replaceWith()
.unwrap()
.wrap()
.wrapAll()
.wrapInner()
.prepend()

其他输入来源

document.URL *
document.location.pathname *
document.location.href *
document.location.search *
document.location.hash
document.referrer *
window.name
document.cookie
window.location(href hash等)

以及所有input框,都是极有可能产生XSS攻击的点。

原文地址:https://www.cnblogs.com/liuhuan086/p/14741974.html