CSRF基础

CSRF

原理

在浏览器中cookie在一段时间内是不会过期(不关闭或者退出浏览器),再次访问都会默认登录,这个应该都有体验。如果在cookie存在期间,通过构造csrf脚本或包含csrf脚本的链接发送给用户,得到信息后,再伪造成用户身份,执行相关操作

形象理解:如果将XSS攻击过程比喻为小偷偷取了用户的身份证去办理非法业务,那CSRF攻击则是骗子“劫持” 了用户,让用户自己去办理非法业务,以达到自己的目的。

个人理解:CSRF主要是利用cookie的作用,从而发送非法请求,并且成功登录用户网站。CSRF的主要利用过程就是用户在访问一个网站是,服务器会生成一个cookie并返回用户保存在用户浏览器客户端上,而攻击者可以设置一个非法的链接,诱导用户点击,然后攻击者会通过一下js代码想网站发送非法请求,由于攻击者是借助用户而发起的非法请求,所以请求中会带有用户的cookie信息,从而能够登录网站,实现非法操作。

流程:

流程:

步骤一
用户登录、浏览并信任正规网站WebA,同时,WebA通过用户的验证并在用户的浏览器中产生Cookie。
在这里插入图片描述

步骤二
攻击者WebB通过在WebA中添加图片链接等方式诱导用户User访问网站WebB。
在这里插入图片描述

步骤三
在用户User被诱导访问WebB后,WebB会利用用户User的浏览器访问第三方网站WebA,并发出操作请求。
在这里插入图片描述

步骤四
用户User的浏览器根据WebB的要求,带着步骤一中产生的Cookie访问WebA。
在这里插入图片描述

步骤五
网站WebA接收到用户浏览器的请求,WebA无法分辨请求由何处发出,由于浏览器访问时带上用户的Cookie,因此WebA会响应浏览器的请求,如此一来,攻击网站WebB就达到了模拟用户操作的目的。
在这里插入图片描述

条件

,实现CSRF的条件有以下几方面

  1. 服务器必须可以识别用户身份
  2. 攻击者必须知道网站正确的URL
  3. 攻击者必须诱导用户去点击正确的URL

特点

攻击一般发起在第三方网站,而不是被攻击的网站,被攻击的网站无法预防发生
攻击者利用受害者的凭证进行请求操作,而不是直接窃取数据
整个过程并不能获取受害者的登陆凭证,仅仅是冒用
跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入第三方论坛、文章中,难以追踪。
CSRF通常是跨域的,因为外域通常更容易被攻击者掌握,但是如果本域下有容易被利用的功能,比如可以发图和链接的论坛和评论区,攻击者可以在本域进行,这样更加危险。

分类

get型

这种的非常简答,只用一个http请求就行,这种是发送的get请求。所以攻击者只要诱导目标点击链接就能够向目标网站发送一个以受害者身份的恶意访问。

例如pikachu上面的一道题;

image-20220601220518546

当我们提交修改信息的按钮时进行抓报,在报文里面能够看到修改内容

复制出信息

GET /pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=CSRF&phonenum=13137798532&add=chain&email=%E5%B0%8F%E9%83%AD%40pikachu.com&submit=submit

我们可以修改参数,然后添加补全网址

http://127.0.0.1/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=你好,hacker&phonenum=1862222222222&add=chain&email=%E5%B0%8F%E9%83%AD%40pikachu.com&submit=submit

image-20220601221037049

诱导目标点击链接后发现内容已经被修改

image-20220601221155082

表单:

POST型

这类的CSRF利用通常是使用一种自动提交的表单

<form action="http://a.com/withdraw" method=POST>
    <input type="hidden" name="account" value="airing" />
    <input type="hidden" name="amount" value="10000" />
    <input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>

访问该页面后,表单会自动提交,相当于模拟用户完成了一次 POST 操作。可见这种类型的 CSRF 与第一种一样,都是模拟请求,所以后端接口也不能将安全寄托在仅允许 POST 请求上。

链接类型的 CSRF

链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发,但本质上与前两种一样。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如

<a href="http://a.com/withdraw.php?amount=1000&for=hacker" taget="_blank">
 屠龙宝刀,点击就送! 
<a/>

由于用户之前登录过,所以点击链接就会攻击成功。

CSRF容易出现的位置

一般是增删修改的地方容易出现CSRF漏洞

防御CSRF

验证码

使用验证码验证可以解决大多数的CSRF问题,但是由于用户考虑,不可能每步操作都进行验证,所以只有在一些重要的用户和数据交互的场景进行验证。

验证Refer

查 HTTP Referer 字段是否同域 HTTP Referer 是 header 的一部分。当浏览器向服务端发送请求时,浏览器会带上 Referer,用于告诉服务端请求的来源。一般来说,用户提交的站内请求的来源(也就是 Referer 字段)应该站
地址,当检测到非同域时,有理由怀疑用户受到了 CSRF 攻击。

但是这种方法的现实意义不大,因为refer是可以修改的,所以一旦攻击者获取到用户refer就可以修改refer绕过检测

我们可以限制session cookie的生存周期,当到达一定时间就销毁session cookie,避免攻击者发动CSRF攻击。

但是这种方法在现实中意义也不是很大,因为这种是用户在关闭浏览器是并不会直接销毁cookie,这会让攻击者的攻击得以进行,虽然可以在用户关闭浏览器时给服务端发送一个销毁 Session 的请求,但是当浏览器崩溃或被强制关闭时,销毁 Session 的请求无法发出,服务端就一直会保持着这个 Session。

token验证

在请求地址中添加token验证,攻击者的攻击之所以能够成功,是因为伪造了用户的信息,而请求中的验证信息都存在于cookie中,攻击者完全可以伪造cookie来绕过验证,所以我们可以在请求中放入用户不能伪造的信息token,并且token不能存在于cookie中,可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

get型:http://url?csrftoken=tokenvalue。

post型:(加在form的最后)

在 HTTP 头中自定义属性并验证

这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。
然而这种方法的局限性非常大。XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便。另外,对于没有进行 CSRF 防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。(网上复制)

posted @ 2022-10-27 11:10  GTL_JU  阅读(64)  评论(0编辑  收藏  举报