跨站脚本攻击(XSS)

XSS——通过“HTML 注入” 篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器。

XSS 分类:

1. 反射性 XSS:把用户输入的数据 “反射” 给浏览器,往往需要诱使用户 “点击” 一个恶意链接,也叫非持久型 XSS。

2. 存储型 XSS:把用户输入的数据 “存储” 在服务器端,当其他用户打开包含有该数据的页面时执行其中可能包含的脚本,也叫持久型 XSS。

3. DOM Based XSS:反射型 XSS 的一种,通过修改页面的 DOM 节点来实现。

XSS 的典型攻击:Cookie 劫持

XSS Payload:XSS 攻击成功后,攻击者能通过对用户当前浏览的页面植入恶意脚本来控制用户的浏览器。该恶意脚本即为 XSS Payload。

XSS 攻击手法:

1. 构造 GET 与 POST 请求:一个网站的应用,只要接受 HTTP 协议中的 GET 或 POST 请求,即可完成所有操作。那么攻击者同样只需要通过注入 JavaScript 等脚本发起这两种请求,就可以达到攻击的目的。

2. XSS 钓鱼:注入恶意脚本,在当前页面上 “画出” 一个伪造的信息输入框(比如登录框),当用户在信息输入框中输入敏感信息并提交后,该数据将被发送到黑客的服务器上。

3. 识别用户浏览器、操作系统、已安装的软件等:查看 UserAgent,ActiveX 的 classid 等。

4. 网站浏览历史记录:CSS History Hack,浏览器会将点击过的链接以不同的颜色显示。

5. 获取用户真实 IP:借助某些语言(比如 Java)的 API 获取用户的出口 IP。

XSS 构造技巧:

1. 利用字符编码:GBK/GB2312、utf-8,不同浏览器对字符编码的支持方式不一样。在字符编码的转换过程中可能产生或隐去特殊的字符,借此可以构造攻击脚本,绕过安全过滤。

2. 绕过长度限制:把 XSS Payload 写到别处,然后通过简短的代码加载进来。location.hash(URL 中用于设定页面内位置的一段字符,以“#”开头,没有长度限制) 是隐藏 XSS Payload 的好地方。

3. 利用<base>标签:<base>标签指定页面加载资源的默认源(在不指定的情况下默认源为当前域),通过注入<base>标签,指定资源默认源,可以导入恶意站点的资源。

4. 利用 window.name 属性: 对 window.name 对象赋值没有特殊字符的限制,而且该属性能够跨域传递,在跳转的后续站点只需要 eval(name) 就可以执行 window.name 对象的值对应的脚本字符串。

其他 XSS 漏洞表现形式:

1. 原样输出用户输入的内容:eg. Apache Expect Header XSS

2. 将想要利用的反射型 XSS 嵌入到一个存储型 XSS 中,如果在 B 域上存在一个反射型 “XSS_B”,在 A 域上存在一个存储型 “XSS_A”,当用户访问 A 域上的 “XSS_A” 时,同时嵌入 B 域上的 “XSS_B”,从而达到 A 域的 XSS 攻击 B 域用户的目的。在 IE 上<iframe>、<img>、<link>标签会拦截第三方 Cookie 的发送。Firefox 上嵌入<iframe>标签,IE 上嵌入<form> 标签。

3. Flash XSS:在 Flash 中可以嵌入 ActionScript 脚本。

4. JavaScript 开发框架中可能存在 XSS:Dojo、YUI、jQuery。

XSS 攻击平台:Attack API、BeEF、XSS-Proxy

XSS Worm:XSS 蠕虫攻击,传播带有恶意链接的页面,该页面带有恶意链接。

JavaScript 调试工具:Firebug(已集成到 Firefox)、IE 8 Develop Tool、Fiddler、HttpWatch

 

XSS 的防御

 1. HttpOnly

在创建页面 Cookie 时添加 HttpOnly 属性,禁止(JavaScript 等)脚本读取 Cookie,从而避免 XSS 攻击泄露 Cookie。

在不同的语言中,给 Cookie 添加 HttpOnly 的方法:

Java EE:response.setHeader("Set-Cookie", "cookiename=value; Path=/; Domain=domainvalue; Max-Age=secondes; HTTPOnly");

C#:HttpCookie myCookie = new HttpCookie("myCookie"); myCookie.HttpOnly = true; Response.AppendCookie(myCookie);

VB.NET:Dim myCookie As HttpCookie = new HttpCookie("myCookie"); myCookie.HttpOnly = True; Response.AppendCookie(myCookie); 

.NET 1.1:Response.Cookies[cookie].Path += ";HTTPOnly";

PHP 4:header("set-Cookie: hidden=value; httpOnly");

PHP 5:setcookie("abc", "test", NULL, NULL, NULL, NULL, TRUE);

2. 输入检查

输入检查的逻辑必须放在服务器端代码中实现,客户端使用 JavaScript 只能做辅助。XSS Filter 过滤用户输入中的敏感字符,防止插入恶意代码。【弱】

3. 输出检查

(1)安全的编码函数:

① HtmlEncode:将字符转换成 HTMLEntities,对应 ISO-8859-1 标准。

② htmlentities()、htmlspecialchars():PHP 中将字符转换成 HTMLEntities 的函数。

③ JavascriptEncode:JavaScript 中将字符转换成安全字符的函数。它使用 “\” 对特殊字符进行转义。在对抗 XSS 时,要求输出的变量必须在引号内部以保安全,例如 var x = "$var2"。

④ XMLEncode 与 HTMLEncode 类似,JASONEncode 与 JavascriptEncode 类似。

(2)安全编码实现方式:

① OWASP ESAPI 对 HtmlEncode、JavascriptEncode 的实现:ESAPI.encoder().encodeFor[...](request.getParameter("input"));

②re Apache Common Lang 的 “StringEscapeUtils” 里提供 escape 函数。

③ Django 开发框架自带的模板系统 “Django Templates” 中可以使用 escape 进行 HtmlEncode,例如 {{ var|escape }}。

4. 正确防御 XSS

XSS 的本质——“HTML 注入”,如果网站使用了 MVC 架构,则 XSS 发生在 View 层。用户输入数据被填充到 HTML 代码中的场景:

(1)HTML 标签,防御方法:对变量使用 HtmlEncode

(2)HTML 属性,防御方法:对变量使用 HtmlEncode

(3)<script>标签,防御方法:① 确保输出的变量在引号中;② 对变量使用 JavascriptEncode

(4)在事件(event)中,防御方法:对变量使用 JavascriptEncode

(5)在 CSS 中,防御方法:对变量使用 “CSSEncode”,比如 ESAPI.encoder().encodeForCSS

(6)在地址中,防御方法:① 如果变量是整个 URL,则应该先检查变量是否以 “http(s)” 开头,如果不是则自动添加该协议头 ② 对地址做 URLEncode,比如 ESAPI.encoder().encodeForURL

(7)富文本编辑器中,防御方法:在标签的选择上使用白名单,避免使用黑名单。htmlparser 可以解析出 HTML 代码的标签、标签属性和事件,可用于识别富文本中的事件代码,进而过滤存在安全隐患的脚本。

5. 防御 DOM Based XSS

防御方法:在不同的场景使用对的编码方法——变量输出到<script>时应该做一次 (Java)scriptEncode,输出到 HTML 时应该做一次 HtmlEncode,一次都不能遗漏。

DOM Based XSS 注入点:

(1)JavaScript 输出到 HTML:document.write()、document.writeln()、xxx.innerHTML=、xxx.outerHTML=、innerHTML.replace、document.attachEvent()、window.attachEvent()、document.location.replace()、document.location.assign()......

(2)变量或 Form:页面中所有的 inputes 框、window.location(href、hash 等)、window.name、document.reffer、document.cookie、localstorage、XMLHttpRequest 返回的数据......

不同类型 XSS 的风险

一般存储型 XSS 的风险高于反射型 XS,存储型 XSS 保存在服务器上,有可能跨页面存在。它不改变页面 URL,因此不容易被检测到。

从攻击过程看,反射型 XSS 一般要求攻击者诱使用户点击一个包含 XSS 代码的 URL;而存储型 XSS 只需让用户查看一个正常的 URL 链接,因此存储型 XSS 漏洞隐蔽性强,风险高。

posted @ 2017-05-10 16:48  RickyShilx  阅读(1019)  评论(0编辑  收藏  举报