作者:手浪用户穹谷之鹰 | 来源:互联网 | 2023-09-16 07:48
CSRFCSRF是CrossSiteRequestForgery的缩写,翻译过来就是跨站请求伪造。跨站:顾名思义,就是从一个网站到另一个网站。请求:即HTTP请求。伪造:在这里可以
CSRF
CSRF是Cross Site Request Forgery的缩写,翻译过来就是跨站请求伪造。
- 跨站:顾名思义,就是从一个网站到另一个网站。
- 请求:即HTTP请求。
- 伪造:在这里可以理解为仿造、伪装。
- 综合起来的意思就是:从一个网站A中发起一个到网站B的请求,而这个请求是经过了伪装的,伪装操作达到的目的就是让请求看起来像是从网站B中发起的,也就是说,让B网站所在的服务器端误以为该请求是从自己网站发起的,而不是从A网站发起的。
- CSRF 攻击是黑客借助受害者的 COOKIE 骗取服务器的信任,但是黑客并不能拿到 COOKIE,也看不到 COOKIE 的内容。另外,对于服务器返回的结果,由于浏览器同源策略的限制,黑客也无法进行解析。因此,黑客无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。所以,我们要保护的对象是那些可以直接产生数据改变的服务,而对于读取数据的服务,则不需要进行 CSRF 的保护。
原理
图片来源: CSRF攻击原理以及nodejs的实现和防御
从上图可以看出,要伪装成从A网站发起请求,必须依次完成两个步骤:
1.登录受信任网站A,并在本地生成COOKIE。
2.在不登出A的情况下,访问危险网站B。
- 之所以要伪装成从A网站发起,是因为COOKIE是不能跨域发送的。结合上面这个例子来说就是:如果从A网站直接发送请求到B网站服务器的话,是无法将A网站中产生的COOKIE一起发给B服务器的。
- 为什么要发送COOKIE呢?这是因为服务器在用户登录后会将用户的一些信息放到COOKIE中返回给客户端,然后客户端在请求一些需要认证的资源的时候会把COOKIE一起发给服务器,服务器通过读取COOKIE中的信息来进行用户认证,认证通过后才会做出正确的响应。
- B网站访问A网站服务器的一些需要认证的资源的时候,如果没有COOKIE信息,服务器是拒绝访问的,那么B网站就无法进行恶意操作。而伪造成AB网站的请求,就可以将A网站的COOKIE一起发到A服务器,这个时候就服务器就认为该请求是合法的,就会给出正确的响应,这个时候,B网站就达到目的了。
危害
攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账……造成的问题包括:个人隐私泄露以及财产安全。
如何防止CSRF攻击
CSRF攻击之所以能够成功,是因为黑客可以完全伪造用户请求,该请求中所有的用户验证信息都是存在于COOKIE中,因此黑客可以在不知道这些验证信息的情况下直接利用用户的COOKIE来通过安全验证。要抵御CSRF,关键在于在请求中放入黑客无法伪造的信息。
对于关键操作使用post方法:
现在的浏览器出于安全考虑,默认都做了一定的限制,form标签发送到其他网站的请求会被拦截
使用验证码:
强制用户必须与应用进行交互,才能完成最终的请求。例如:用户的每次提交表单行为都需要填写一个验证码
在请求地址中添加token并验证 Anti CSRF Token
- 服务端在收到路由请求时,生成一个随机数,在渲染请求页面时把随机数埋入页面(一般埋入 form 表单内,)
- 服务端设置setCOOKIE,把该随机数作为COOKIE或者session种入用户浏览器
- 当用户发送 GET 或者 POST 请求时带上_csrf_token参数(对于 Form 表单直接提交即可,因为会自动把当前表单内所有的 input 提交给后台,包括_csrf_token)
- 后台在接受到请求后解析请求的COOKIE获取_csrf_token的值,然后和用户请求提交的_csrf_token做个比较,如果相等表示请求是合法的。
注意:
- Token 最好保存在 Session 中。假如 Token 保存在 COOKIE 中,用户浏览器开了很多页面(同一页面打开了多次)。在一些页面 Token 被使用消耗掉后新的Token 会被重新种入,但那些老的 Tab 页面对应的 HTML 里还是老 Token。这会让用户觉得为啥几分钟前打开的页面不能正常提交
- 尽量少用 GET。假如攻击者在我们的网站上传了一张图片,用户在加载图片的时候实际上是向攻击者的服务器发送了请求,这个请求会带有referer表示当前图片所在的页面的 url。 而如果使用 GET 方式接口的话这个 URL 就形如:
https://xxxx.com/gift?giftId=…
,那相当于攻击者就获取了_csrf_token,短时间内可以使用这个 token 来操作其他 GET 接口。
- 由于用户的COOKIE很容易由于网站的XSS漏洞而被盗取,所以这个方案必须要在没有XSS的情况下才安全。
检测Referer:
Referer,根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该HTTP请求的来源地址。服务器通过检查Referer的值,如果判断
出Referer并非本站页面,而是一个外部站点的页面,那么我们就可以判断出这个请求是非法的
这个方法是实现防止图片盗链的原理
- 优点:这种方法的显而易见的好处就是简单易行,网站的普通开发人员不需要操心 CSRF 的漏洞,只需要在最后给所有安全敏感的请求统一增加一个拦截器来检查 Referer 的值就可以。特别是对于当前现有的系统,不需要改变当前系统的任何已有代码和逻辑,没有风险,非常便捷。
- 缺点:Referer 的值是由浏览器提供的,虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方(即浏览器)来保障,从理论上来讲,这样并不安全。对于某些低版本浏览器,目前已经有一些方法可以篡改 Referer 值
在HTTP头中自定义属性
这种方法也是使用token并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。
参考:
对CSRF(跨站请求伪造)的理解
浅谈CSRF攻击方式
XSS跨站脚本攻击与CSRF跨站请求伪造攻击的学习总结。\
CSRF攻击原理以及nodejs的实现和防御
CSRF 攻击的应对之道