当前位置:网站首页>Web安全(三)---CSRF攻击

Web安全(三)---CSRF攻击

2020-11-07 20:56:36 Coxhuang

文章目录

  • CSRF攻击
    • #1 什么是CSRF攻击
    • #2 Cookie
    • #3 浏览器的同源策略
    • #3 前后端分离项目如何避免CSRF攻击
      • #3.1 防御一 --- 验证码
      • #3.2 防御二 --- HTTP Referer
      • #3.3 防御三 --- TOKEN

CSRF攻击

#1 什么是CSRF攻击

CSRF跨站点请求伪造(Cross—Site Request Forgery)

攻击者盗用了你的身份(TOKEN或Cookie等认证),以你的名义往服务器发请求,这个请求对于服务器来说是完全合法的,但是却完成了攻击者所希望的操作,而你全然不知,例如:以你的名义发送邮件,转账之类的操作

CSRF攻击过程 :

  1. 用户Tom打开浏览器,访问 https://weibo.com/, 输入账号密码登录微博
  2. 微博后台验证账号密码通过之后,会返回一个Cookie,保存到浏览器中,此时用户登录成功,并能够像微博发送请求
  3. 在用户没用退出微博登录时,打开另一个网站A,网站A接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问微博
  4. 浏览器在接收到这些攻击性代码后,根据网站A的请求,在用户不知情的情况下,携带Cookie往微博发请求,对微博后台来说,这个请求是完全合法的,所以会根据用户Tom的Cookie信息以Tom的权限处理该请求,导致来自网站A的恶意代码被执行。

CSRF攻击实例 :

小明使用浏览器登录银行网站后,银行后台会返回一个Cookie并存到小明电脑的浏览器中,在这个Cookie还没有过期之前,小明点击了浏览器弹出的广告,此时跳转到另外一个网站A,网站A有一段恶意代码,代码内容是: 往银行后台发送一个转账的请求(携带Cookie),这时,悲剧发生了,这个 url 请求就会得到响应,钱将从小明的账号转移到攻击者的账号,而小明当时毫不知情,等以后小明发现账户钱少了,即使他去银行查询日志,他也只能发现确实有一个来自于他本人的合法请求转移了资金,没有任何被攻击的痕迹。

正常的CSRF攻击,攻击发送的请求默认会自动携带Cookie

Cookie字段

含义

NAME=VALUE

赋予 Cookie 的名称和其值(必需项)

expires=DATE

Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止)

path=PATH

将服务器上的文件目录作为Cookie的适用对象(若不指定则默认为文档所在的文件目录)

domain=域名

作为 Cookie 适用对象的域名 (若不指定则默认为创建 Cookie的服务器的域名)

Secure

仅在 HTTPS 安全通信时才会发送 Cookie

HttpOnly

加以限制, 使 Cookie 不能被 JavaScript 脚本访问

对于一个Http POST请求 http://xxx.minhung.me/ooooo/create-msg来说

如果满足下面几个条件:

  • 浏览器端某个Cookie的domain字段等于xxx.minhung.me或者minhung.me
  • 都是http或者https,或者在不同的情况下Secure属性为false
  • 要发送请求的路径,即上面http://xxx.minhung.me/ooooo/create-msg的ooooo跟浏览器端Cookie的path属性必须一致,或者是浏览器端Cookie的path的子目录,比如浏览器端Cookie的path为/test,那么ooooo必须为/test或者/test/xxxx等子目录才可以

上面3个条件必须同时满足,否则该Post请求就不能自动带上浏览器端已存在的Cookie

因为在CSRF攻击中,访问的就是设置Cookie的服务端的接口,所以访问的时候会自动携带Cookie

#3 浏览器的同源策略

浏览器的同源策略,总的而言有以下三点限制:

  • 一是来自一个源的js只能读写自己源的存储不能读写其他源的存储,存储包括Cookie、Session Storage、Local Storage、Cache、Indexed DB等。
  • 二是来自一个源的js只能读写自己源的DOM树不能读取其他源的DOM树。即如果开始讨论,iframe内外层不同源就不能相互操作,外层想获取内层的内容只能使用点击劫持配合;实现原理亦如前所述未知。
  • 三是一般而言来自一个源的js只能向自己源的接口发送请求不能向其他源的接口发送请求。当然其实本质是,一方面浏览器发现一个源的js向其他源的接口发送请求时会自动带上Origin头标识来自的源,让服务器能通过Origin判断要不要向应;另一方面,浏览器在接收到响应后如果没有发现Access-Control-Allow-Origin允许发送请求的域进行请求那也不允许解析。自己之前也抱怨过,又不是服务器不响应服务器响应了不浏览器不(允许js)解析是不是没什么意义的多此一举;现在看来,通过自己写python等方法也确实能请求其他服务器并解析其结果,浏览器没有Access-Control-Allow-Origin允许不解析一是说维护了自己同源策略的思想二是说至少可以保证不会在自己身上出现A域可随便探测B域的情况,所以也不能说完全没用。
  • 四是来自一个源的js不能随意操作浏览器之外的资源。比如打开命令提示符、执行系统命令等等。倘若你访问一个网站该网站的js可以直接调用系统命令给你电脑进行添加用户等操作,那问题就大了。

在浏览器的同源策略下, 其他站点的js是不能读写别的站点的Cookie、Session Storage、Local Storage、Cache、Indexed DB

#3 前后端分离项目如何避免CSRF攻击

防御方案 :

  • 用户操作限制,比如验证码
  • 请求来源限制,比如限制HTTP Referer才能完成操作
  • token验证机制,比如请求数据字段中添加一个token,响应请求时校验其有效性

#3.1 防御一 — 验证码

发送请求时,需要验证码验证是否是用户本人,次方案明显严重影响了用户体验,而且还有额外的开发成本

#3.2 防御二 — HTTP Referer

次方案成本最低,但是并不能保证100%安全,而且很有可能会埋坑

Referer 是 HTTP 请求header 的一部分,当浏览器(或者模拟浏览器行为)向web 服务器发送请求的时候,头信息里有包含 Referer 。比如我在www.google.com 里有一个www.baidu.com 链接,那么点击这个www.baidu.com ,它的header 信息里就有:

Referer=http://www.google.com

所以,将这个http请求发给服务器后,如果服务器要求必须是某个地址或者某几个地址才能访问,而你发送的referer不符合他的要求,就会拦截或者跳转到他要求的地址,然后再通过这个地址进行访问。

#3.3 防御三 — TOKEN

用户登录成功后,服务端将用户名和一些关键数据生成一个Token,将Token封装到Cookie中,然后发送给客户端,每次客户端发送请求时,先获取Cookie中的Token,再携带该Token访问服务端

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

版权声明
本文为[Coxhuang]所创,转载请带上原文链接,感谢
https://cloud.tencent.com/developer/article/1744584