[TOC]

原文链接:https://www.yuque.com/1ncounter/courtyard/bk34lz ,作者:1ncounter
跨站脚本(Cross-site Script),按理应该简称为 CSS,但为了与层叠样式表(CSS)区分开,特意改为 XSS。

XSS 漏洞的分类

通常 XSS 分为存储型和反射型,但还有一种比较特殊的 DOM 型 XSS,它本身属于反射型 XSS。因此,就按 3 种类型划分:反射型、存储型、DOM 型。

反射型 XSS

反射型 XSS 又被称为非持久型跨站脚本,它是将攻击代码放在 URL 参数中,而不是存储到服务器,因此需要诱使用户点击才能触发攻击。

存储型 XSS

存储型 XSS,它又被称为持久型跨站脚本。攻击者将恶意代码存储到服务器上,只要诱使受害者访问被插入恶意代码的页面即可触发。存储型 XSS 经常出现在一些可以发表评论的地方,如帖子、博客。
存储型 XSS 的特点就是不需要在诱使用户访问的URL中包含攻击代码,因为它已经存储到了服务器中,只需要让用户访问包含输出攻击代码的页面即可。

DOM 型 XSS

它是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,它不经过服务端,而是通过 URL 传入参数去触发,因此也属于反射型 XSS。
由于客户端的JavaScript可以访问浏览器页面中的 DOM 对象,因此它能够决定如何处理当前页面的 URL,比如获取 URL 中的相关数据进行处理,然后动态更新到页面上。这导致 DOM 型 XSS 的漏洞代码常位于网页的 JavaScript 代码中。
网上曾有人整理了一份关于 DOM XSS 的数据污染源(Source,即用户输入数据)和漏洞触发点(Sink)的列表(虽然不够全面,但可以作为参考),如下图所示:

XSS(转载) - 图1

若数据从 Source 传到 Sink 过程中,未做任何过滤,就有可能存在 DOM XSS。这个思路也常作为动静态检测 DOM XSS 的重要思路。

攻击 XSS 漏洞

针对 XSS 漏洞最为常见的两种攻击方式就是窃取 Cookie 劫持他人的会话,以及蠕虫攻击

窃取 Cookie

Cookie是由服务器提供的存储在客户端的数据,允许 JavaScript 访问,常用于识别用户身份和保存会话等功能。如果 Web 应用程序存在 XSS 漏洞,那么攻击者通过注入恶意 JavaScript 脚本就可以窃取到 Cookie,进而以用户身份执行恶意操作。

蠕虫攻击

XSS 蠕虫的实现正是得益于Ajax 技术的出现,而后者正是 Web2.0的标志性技术。
以微博XSS攻击为例,该 XSS 蠕虫的攻击流程:

  1. 利用 XSS 漏洞插入恶意 JS 代码;
  2. 利用 XmlHttpRequest 发送请求去发表微博、关注用户、获取关注者列表并向其发送私信;
  3. 微博消息和私信都包含有恶意攻击链接,等于实现了攻击代码的自我复制和传播。

一个完整的 XSS 蠕虫常常具备如下特征:

  1. 目标网站存在 XSS 漏洞;
  2. 攻击代码的自我复制和传播,其传播方式依赖于业务场景,更多是在社交功能上,比如博客、私信、微博、评论。

    其他攻击方法

    在 XSS 漏洞攻击场景下,凡是 JavaScript 能够实现功能,你都可以自由发挥,实现不同的攻击方法。

    XSS 漏洞挖掘

    XSS 漏洞挖掘的方法可以按有无源码的情况分为黑盒测试和白盒测试。
    黑盒测试主要是通过发送特意构造攻击字符串来验证漏洞,比如 <script> alert(1)</script>。请求后看是否会弹框,若会则代表存在 XSS,反之则不存在。
    白盒测试是通过分析源代码来检测 XSS 漏洞,根据不同的编程语言采取不同的词法、语法分析方式,然后通过污点分析(追踪用户的输入数据是否达到特定的漏洞触发函数)的思路来检测漏洞。

    防御 XSS 攻击

    输入检查

    在测试 XSS 时,经常需要输入一些特殊字符,所以在一开始直接做好输入检查有利于减少攻击的可能性。我在协助业务修复漏洞的时候,经常推荐的方法就是白名单限制,比如参数是个整数值,那直接限制死即可,若不符合就抛异常。不要单纯只想着过滤替换特殊字符,这很容易就被绕过了。
    如果白名单范围不好确定,我就会采用黑名单的方式,把常用的 XSS payload 特殊字符或字符串做检测,比如