1、XSS简介
- XSS全称为Cross Site Scripting,为了和CSS分开简写为XSS,中文名为跨站脚本攻击
- 该漏洞发生在用户端,是指在渲染过程中发生了不在预期过程中的JavaScript代码执行
- XSS通常被用于获取Cookie、以受攻击者的身份进行操作等行为
1、网站中包含大量的动态内容以提高用户体验,比过去要复杂得多
2、所谓动态内容,就是根据用户环境和需要,Web应用程序能够输出相应的内容
3、动态站点会受到一种名为跨站脚本攻击的威胁,而静态站点则完全不受其影响
2、XSS攻击的流程
- 用户在浏览网站、使用即时通讯软件、甚至在阅读电子邮件时,通常会点击其中的链接
- 攻击者通过在链接中插入恶意代码,就能够盗取用户信息
- 攻击者通常会用十六进制(或其他编码方式)将链接编码,以免用户怀疑它的合法性
- 网站在接收到包含恶意代码的请求之后会产成一个包含恶意代码的页面,而这个页面看起来就像是那个网站应当生成的合法页面一样
- 许多流行的留言本和论坛程序允许用户发表包含HTML和javascript的帖子。假设用户甲发表了一篇包含恶意脚本的帖子,那么用户乙在浏览这篇帖子时,恶意脚本就会执行,盗取用户乙的session信息
3、XSS攻击分类
- 反射型XSS
- 反射型XSS是比较常见和广泛的一类,举例来说,当一个网站的代码中包含类似下面的语句:
<?php echo "<p>hello, $_GET['user']</p>";?>
- 那么在访问时设置
/?user=</p><script>alert("hack")</script><p>
,则可执行预设好的JavaScript代码- 反射型XSS通常出现在搜索等功能中,需要被攻击者点击对应的链接才能触发,且受到XSS Auditor、NoScript等防御手段的影响较大
- 存储型XSS
存储型XSS相比反射型来说危害较大,在这种漏洞中,攻击者能够把攻击载荷存入服务器的数据库中,造成持久化的攻击
- DOM XSS
DOM型XSS不同之处在于DOM型XSS一般和服务器的解析响应没有直接关系,而是在JavaScript脚本动态执行的过程中产生的
例如下面这个代码
<html>
<head>
<title>DOM Based XSS Demo</title>
<script>
function xsstest()
{
var str = document.getElementById("input").value;
document.getElementById("output").innerHTML = "<img src='"+str+"'></img>";
}
</script>
</head>
<body>
<div id="output"></div>
<input type="text" id="input" size=50 value="" />
<input type="button" value="submit" onclick="xsstest()" />
</body>
</html>
输入 x' onerror='javascript:alert(/xss/)
即可触发
- Blind XSS
- Blind XSS是储存型XSS的一种,它保存在某些存储中,当一个“受害者”访问这个页面时执行,并且在文档对象模型(DOM)中呈现payload
- 它被称为Blind的原因是因为它通常发生在通常不暴露给用户的功能上
4、XSS攻击的危害
存在XSS漏洞时,可能会导致以下几种情况:
- 用户的Cookie被获取,其中可能存在Session ID等敏感信息。若服务器端没有做相应防护,攻击者可用对应Cookie登陆服务器
- 攻击者能够在一定限度内记录用户的键盘输入
- 攻击者通过CSRF等方式以用户身份执行危险操作
- XSS蠕虫
- 获取用户浏览器信息
- 利用XSS漏洞扫描用户内网
- 随着AJAX(Asynchronous JavaScript and XML,异步JavaScript和XML)技术的普遍应用,XSS的攻击危害将被放大
- 使用AJAX的最大优点,就是可以不用更新整个页面来维护数据,Web应用可以更迅速地响应用户请求
- AJAX会处理来自Web服务器及源自第三方的丰富信息,这对XSS攻击提供了良好的机会
- AJAX应用架构会泄漏更多应用的细节,如函数和变量名称、函数参数及返回类型、数据类型及有效范围等
- AJAX应用架构还有着较传统架构更多的应用输入,这就增加了可被攻击的点
5、如何预防XSS攻击
- 从网站开发者角度,如何防护XSS攻击?
来自应用安全国际组织OWASP的建议,对XSS最佳的防护应该结合以下两种方法:
1、验证所有输入数据
2、有效检测攻击
对所有输出数据进行适当的编码,以防止任何已成功注入的脚本在浏览器端运行
-
输入验证:某个数据被接受为可被显示或存储之前,使用标准输入验证机制,验证所有输入数据的长度、类型、语法以及业务规则
-
输出编码:数据输出前,确保用户提交的数据已被正确进行entity编码,建议对所有字符进行编码而不仅局限于某个子集
-
明确指定输出的编码方式:不要允许攻击者为你的用户选择编码方式(如ISO 8859-1或 UTF 8)
-
注意黑名单验证方式的局限性:仅仅查找或替换一些字符(如"<" ">"或类似"script"的关键字),很容易被XSS变种攻击绕过验证机制
-
警惕规范化错误:验证输入之前,必须进行解码及规范化以符合应用程序当前的内部表示方法。请确定应用程序对同一输入不做两次解码
-
从网站用户角度,如何防护XSS攻击?
-
当你打开一封Email或附件、浏览论坛帖子时,可能恶意脚本会自动执行,因此,在做这些操作时一定要特别谨慎。
-
建议在浏览器设置中关闭JavaScript。如果使用IE浏览器,将安全级别设置到“高”
-
这里需要再次提醒的是,XSS攻击其实伴随着社会工程学的成功应用,需要增强安全意识,只信任值得信任的站点或内容
-
可以通过一些检测工具进行xss的漏洞检测,类似工具有亿思网站安全检测平台
-
针对xss的漏洞带来的危害是巨大,如有发现,应立即修复漏洞
6、XSS防御规则
下列规则旨在防止所有发生在应用程序的XSS攻击,虽然这些规则不允许任意向HTML文档放入不可信数据,不过基本上也涵盖了绝大多数常见的情况。你不需要采用所有规则,很多企业可能会发现第一条和第二条就已经足以满足需求了。请根据自己的需求选择规则
- 不要在允许位置插入不可信数据
拒绝所有数据,不要将不可信数据放入HTML文档,除非是下列定义的插槽。
这样做的理由是在理列有解码规则的HTML中有很多奇怪的context,让事情变得很复杂,因此没有理由将不可信数据放在这些context中
- 在向HTML元素内容插入不可信数据前对HTML解码
适用于当你想把不可信数据直接插入HTML正文某处时,这包括内部正常标签(div、p、b、td等)。大多数网站框架都有HTML解码的方法且能够躲开下列字符。但是,这对于其他HTML context是远远不够的,你需要部署其他规则
- 在向HTML常见属性插入不可信数据前进行属性解码
是将不可信数据转化为典型属性值(如宽度、名称、值等),这不能用于复杂属性(如href、src、style或者其他事件处理程序)。这是及其重要的规则,事件处理器属性(为HTML JavaScript Data Values)必须遵守该规则
- 在向HTML JavaScript Data Values插入不可信数据前,进行JavaScript解码
在不同HTML元素上制定的JavaScript事件处理器。向这些事件处理器放置不可信数据的唯一安全位置就是“data value”。在这些小代码块放置不可信数据是相当危险的,因为很容易切换到执行环境,因此请小心使用
- 在向HTML 样式属性值插入不可信数据前,进行CSS解码
当你想将不可信数据放入样式表或者样式标签时,可以用此规则。CSS是很强大的,可以用于许多攻击。因此,只能在属性值中使用不可信数据而不能在其他样式数据中使用。不能将不可信数据放入复杂的属性(如url,、behavior、和custom (-moz-binding))。同样,不能将不可信数据放入允许JavaScript的IE的expression属性值
- 在向HTML URL属性插入不可信数据前,进行URL解码
当你想将不可信数据放入链接到其他位置的link中时需要运用此规则。这包括href和src属性。还有很多其他位置属性,不过我们建议不要在这些属性中使用不可信数据。需要注意的是在javascript中使用不可信数据的问题,不过可以使用上述的HTML JavaScript Data Value规则