演示(想要通过后端获取这个鉴权cookie 【失败】)

目录结构
image.png

前端

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <body>
  4. <!-- img连跨域也没有 -->
  5. <img src="https://被攻击网站域名/api/admin/ad/home_ad" alt="">
  6. <script>
  7. // 这个请求将带着 被攻击网站域名 的cookie
  8. fetch("/hack")
  9. </script>
  10. </body>
  11. </html>

后端

  1. const express = require('express')
  2. const fs = require('fs')
  3. const cookieParser = require("cookie-parser");
  4. const app = express()
  5. const port = 3000
  6. app.use(cookieParser());
  7. app.use('/static', express.static('public'))
  8. app.get('/hack', (req, res) => {
  9. const writePath = `${__dirname}/source/index.json`
  10. fs.appendFile(writePath, JSON.stringify(req.cookies) + ',', (err) => {
  11. if (err) throw err;
  12. console.log('文件已被保存');
  13. });
  14. console.log("cookie", req.cookies)
  15. res.json({ user: 'pong' })
  16. })
  17. app.listen(port, () => console.log(`Example app listening on port ${port}!`))

失败

无法获取跨域cookie,express只能获取当前域名的cookie。

演示二(借用户的手【成功】)

一、找到伪造的地址

image.png

二、找到请求的参数

image.png

三、创建一个表单

image.png

四、open with live server 并发送请求

image.png
image.png
发现请求成功了~,数据也被修改了。
借被攻击人的手去操作


原理

image.png
所以由于script/iframe/img等标签的请求默认是能带上cookie(cookie里面带上了登陆验证的票token),用这些标签发请求是能够绕过同源策略的,因此就可以利用这些标签做跨站请求伪造(CSRF)。

这样当用户在浏览一些依靠cookie鉴权的网站时,如果打开了一个做了csrf的网站,这个网站可能对你的网站做一个违法请求,而且浏览器会带着你的cookie,你的网站会认为这是你操作的。


防御

最简单方案

csrf防御手段很多种我先提供一个我自己的最简单的。
客户端请求时在header上随便带上一个参数,比如就叫Crsf-Token,值是通过js获取cookie中最后一个字符,服务端对于关键的请求,验证一下这个Crsf-Token是否和cookie最后一位相等。这样也省去了MD5、HMAC等加密方式的麻烦。
这种方式利用的是发起csrf攻击的黑客只能用到你的cookie,而不能直接操作这个cookie(不能读,不能写),甚至由于跨域无法读取cookie的限制(演示一)黑客都不知道这个cookie是什么。

方案一(不可靠)

通过验证Origin/Referer判断请求来源是否来自于可信页面,从而确保用户的请求是从可信网站发起的。
这是不可靠的,上边的例子就已经表明了,form表单的提交是可以绕过着同源策略的。

方案二

CSRF Token
CSRF Token机制是目前比较主流的的防御手段,其核心思路是在需要验证的请求中添加一个无法预测,无法使用浏览器策略直接提交的字段
客户端输入用户名密码向服务器发送请求服务端返回一个加密后的令牌,客户端请求时带着这个令牌服务端验证。
CSRF Token可以是POST请求的一个参数、或者是一个自定义的HTTP Header,Token可以存放于标签中、JS变量中、Cookie中、浏览器Local Storage中或者DOM的任何位置。

方案三

后台设置SameCookie=”Struct”
Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
不过这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。
而且这个规则的浏览器兼容性不是太好。

reference

https://zhuanlan.zhihu.com/p/140999218
https://zhuanlan.zhihu.com/p/33132547
http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html