XSS ,全称(Cross Site Scripting, 跨站脚本攻击) 是Web程序中最常见的漏洞。通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。 这些恶意网页程序通常是JavaScript,(实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML)。 当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的. 比如获取用户的Cookie,导航到恶意网站,携带木马等。
作为测试人员,需要了解XSS的原理,攻击场景,如何修复。 才能有效防止XSS的发生
xss的产生
html通过将一些字符特殊地对待来区别文本和标记,例如,小于符号被看作是HTML标签的开始,< title >与< /title > 之间的字符是页面的标题等等。当动态页面中插入的内容含有这些特殊字符(如<)时,浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。Xss的攻击场景
xss类型一般分为三种:第一种:反射型XSS
反射型XSS只是简单的把用户输入的数据“反射”给浏览器,反射型XSS也叫作“非持久型XSS”,不会涉及到数据库的操作,只是对单个用户而言修改网页的代码
可以通过对网页F12进行一个简单的例子: 假设一个页面把用户输入的参数展示到页面上: 正常情况下,用户在文本框输入内容:
request body会如图显示:
而攻击者修改request body 的内容并执行:
_method=PUT&Message=%3Cp%3EAn+Image+with+XSS%3C%2Fp%3E%0D%0A%3Cimg+src%3D%22x%22+onerror%3D%22alert%28%27xss%27%29%22%3E
此时用户输入的的Script,脚本已经被写入页面中,会发现,onerror=“alert(‘XSS’)”在当前页面执行了:
这并不是开发者所希望看到的(反射型是最常见的xss危害类型)
第二种:储存型XSS
储存型XSS会把用户输入的数据“储存”在服务器端。因为涉及到数据库。这种XSS具有很强的稳定性
例:假设一个页面把用户输入的参数展示到页面上: 正常情况下,用户在文本框输入内容:
网页会正常显示刚刚输入的文字:“test text”。
但是如果此时在输入框输入恶意的代码:
><script>alert(/xss/)</scrit>(>是用来闭合input标签的)
当正常用户想要来查看刚刚写的内容时,这条恶意代码就会被浏览器加载并执行 会发现,alert(/XSS/)在当前页面执行了:
(存储型数据库是最直接的危害类型,跨站代码存储在数据库)
第三种:DOM Based XSS
实际上,这种类型的XSS并非按照“数据是否保存在服务器端”来划分的,从效果上来说也是反射型XSS单独划分出来的,因为DOM Based XSS 的形成原因比较特别。这是由于客户端脚本自身解析不正确导致的安全问题。
如何测试xss
方法一 --查看代码,查找关键的变量
客户端将数据传送给Web 服务端一般通过三种方式 Querystring, Form表单,以及cookie. 例如在ASP的程序中,通过Request对象获取客户端的变量
<%
strUserCode = Request.QueryString(“code”);
strUser = Request.Form(“USER”);
strID = Request.Cookies(“ID”);
%>
假如变量没有经过htmlEncode处理, 那么这个变量就存在一个XSS漏洞
方法二 --准备测试代码
"/><script>alert(document.cookie)</script><!--
<script>alert(document.cookie)</script><!--
"onclick="alert(document.cookie)
在网页中的Textbox或者其他能输入数据的地方,输入这些测试脚本, 看能不能弹出对话框,能弹出的话说明存在XSS漏洞
在URL中查看有那些变量通过URL把值传给Web服务器, 把这些变量的值退换成我们的测试的脚本。 然后看我们的脚本是否能执行
方法三: 自动化测试XSS漏洞
现在已经有很多XSS扫描工具了。 实现XSS自动化测试非常简单,只需要用HttpWebRequest类。 把包含xss 测试脚本。发送给Web服务器。 然后查看HttpWebResponse中,我们的XSS测试脚本是否已经注入进去了。
xss漏洞修复
原则就是:不相信用户的输入内容,对每个用户的输入都做严格检查、过滤;在输出的时候,对某些特殊字符进行转义,替换等。
常用方法示例:
1.将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了.
2.只允许用户输入我们期望的数据。 例如:年龄的textbox中,只允许用户输入数字,而数字之外的字符都过滤掉。
3.对数据进行Html Encode 处理
4.过滤或移除特殊的Html标签
5.过滤JavaScript 事件的标签。例如 "onclick=", "onfocus" 等等。
HTML Encode
XSS之所以会发生, 是因为用户修改了代码。 所以我们需要对用户输入的数据进行HTML Encode处理。 将其中的"中括号", “单引号”,“引号” 之类的特殊字符进行编码。
在C#中已经提供了现成的方法,只要调用HttpUtility.HtmlEncode("string ") 就可以了。 (需要引用System.Web程序集)
Fiddler中也提供了很方便的工具, 点击Toolbar上的"TextWizard" 按钮就可以了
ASP.NET中的XSS安全机制
ASP.NET中有防范XSS的机制,对提交的表单会自动检查是否存在XSS,当用户试图输入XSS代码的时候,ASP.NET会抛出一个错误提示,以此达到防范作用
很多新手程序员对安全没有概念, 甚至不知道有XSS的存在。 ASP.NET可以在这一点上做到默认安全。 这样的话就算是没有安全意识的程序员也能写出一个”较安全的网站“。 如果想禁止这个安全特性, 可以通过 <%@ Page validateRequest=“false" %>