• CSRF如何防范


    前言

    CSRF的全程是Cross Site Request Forgery, 即跨站请求伪造。深入了解CSRF后会发现,这种攻击非常危险,并且很容易就忽视掉。那到底什么是CSRF呢,我们通过一个案例来了解一下

    案例

    有这么一个简单的后台页面,可以发表、删除以及编辑文章,点击删除的那个按钮,就可以把一篇文章删掉。因为偷懒,想说如果我把这个功能做成 GET,我就可以直接用一个链接完成删除这件事,在前端几乎不用写到任何代码:

    <a href='/delete?id=3'>删除a>
    
    • 1

    很方便对吧?然后我在后端那边做一下验证,验证 删除的request的cookie 有没有带 session id 上来,也验证这篇文章是不是这个 id 的作者写的,都符合的话才删除文章。

    嗯,听起来该做的都做了啊,我都已经做到:「只有作者本人可以删除自己的文章」了,应该很安全了,难道还有哪里漏掉了吗?

    没错,的确是「只有作者本人可以删除自己的文章」,但如果他不是自己「主动删除」,而是在不知情的情况下删除呢?你可能会觉得我在讲什么东西,怎么会有这种事情发生,不是作者主动删的还能怎么删?

    好,我就来让你看看还能怎么删!

    今天假设小黑是一个邪恶的坏蛋,想要让小明在不知情的情况下就把自己的文章删掉,该怎么做呢?
    小黑知道小明很喜欢心理测验,于是就做了一个心理测验网站,并且发给小明。但这个心理测验网站跟其他网站不同的点在于,「开始测验」的按钮代码长得像这样:

    <a href='https://Livingblog.com/delete?id=3'>开始测试a>
    
    • 1

    是不是觉得开始不对劲了?

    小明收到网页之后很开心,就点击「开始测验」。点击之后浏览器就会发送一个 GET 请求https://Livingblog.com/delete?id=3,并且因为浏览器的运行机制,一并把 Livingblog.com 的 cookie 都一起带上去。

    Server 端收到之后检查了一下 session,发现是小明,而且这篇文章也真的是小明发的,于是就把这篇文章给删除了。

    这就是CSRF, 你现在明明在心理测验网站,假设是 https://test.com 好了,但是却在不知情的状况下删除了 https://Livingblog.com 的文章

    更有甚者,如果把get请求放在一张看不见的图片链接里:

    <img src='https://Livingblog.com/delete?id=3' width='0' height='0' />
    
    • 1

    那更是神不知鬼不觉了
    我们举的例子是删除文章,这你可能觉得没什么,那如果是银行转帐呢?如果你不幸负责了银行网站的代码编写,而你没有对CSRF攻击进行干预。攻击者只要在自己的网页上写下转帐给自己帐号的 code,再把这个网页散布出去就好,就可以收到一大堆钱。

    回合一:

    :我把请求方法换成post请求怎么样,这样不就无法透过 或是 来攻击了吗
    CSRF:简单~,我用form表单元素

    <form action="https://Livingblog.com/delete" method="POST">
      <input type="hidden" name="id" value="3"/>
      <input type="submit" value="开始测试"/>
    form>
    
    • 1
    • 2
    • 3
    • 4

    并且我开一个看不见的 iframe,让 form submit 之后的结果出现在 iframe 里面,而且这个 form 还可以自动 submit,完全不需要经过用户的任何操作

    <iframe style="display:none" name="csrf-frame">iframe>
    <form method='POST' action='https://small-min.blog.com/delete' target="csrf-frame" id="csrf-form">
      <input type='hidden' name='id' value='3'>
      <input type='submit' value='submit'>
    form>
    <script>document.getElementById("csrf-form").submit()script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    回合二:

    :那后端改成只接收 json 呢?
    CSRF:笑死,如果你的 api 的 Access-Control-Allow-Origin 设成 * 的话,代表任何 domain 都可以发送 ajax 到你的 api server,这样无论你是改成 json,或是把 method 改成 PUT, DELETE 都没有用。

    回合三:

    :妈的,那请求我都带上图像验证,或者是短信验证。
    CSRF:好吧,那我确实没办法了,网页的重要操作也确实是这么干的,但如果使用者每次删除 blog 都要打一次图形验证码,他们应该会烦死吧。

    回合四:

    :可恶啊,CSRF不可小觑啊,我要认真思考了。要防止 CSRF 攻击,我们其实只要确保有些资讯「只有使用者知道」即可。那该怎么做呢?

    我在 form 里面加上一个 hidden 的栏位,叫做csrftoken,这里面填的值由 server 随机产生,并且存在 server 的 session 中。

    按下 submit 之后,server 比对表单中的csrftoken与自己 session 里面存的是不是一样的,是的话就代表这的确是由使用者本人发出的 request。这个 csrftoken 由 server 产生。

    <form action="https://Livingblog.com/delete" method="POST">
      <input type="hidden" name="id" value="3"/>
      <input type="hidden" name="csrftoken" value="fj1iro2jro12ijoi1"/>
      <input type="submit" value="刪除文章"/>
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    因为攻击者并不知道 csrftoken 的值是什么,也猜不出来,所以自然就无法进行攻击了。

    CSRF:可是有另外一种状况,如果你的 server 支持跨域的请求,会发生什么事呢?我就可以在你的页面发起一个 request,顺利拿到这个 csrftoken 并且进行攻击。不过前提是你的 server 接受这个 domain 的 request。

    回合五:

    :那我再想想,延续「有些资讯只有使用者知道即可」的思路,继续在 server 产生一组随机的 token 并且加在 form 上面。但不同的点在于,除了不用把这个值写在 session 以外,同时也让客户端设定一个名叫 csrftoken 的 cookie,就是在form表单里和cookie里同时放一个值是一样的csrftoken 。这样的话,由于浏览器的限制——攻击者没法获取到cookie,只是在发起请求时会携带。那攻击者自然也就无法在form表单里填上与cookie一致的csrftoken。我在server里一对比就能知道了是恶意提交了!

    CSRF:看似完美,可惜还是不够,看这个:双提交cookie的脆弱 :double-submit-cookies-vulnerabilities。阅读cookie是很难,可我可以自己伪造一个cookie,没想到吧

    回合六:

    :(眉头紧皱),那浏览器呢? CSRF之所以能成,是因为浏览器的机制所导致的,有没有可能从浏览器方面下手,来解决这个问题呢?Google 在 Chrome 51 版的时候正式加入了这个功能:SameSite cookie。在设置cookie的时候加上了这个功能。那么只要是浏览器验证不是在同一个 site 底下发出的 request,全部都不会带上这个 cookie。
    CSRF:试着用吧, 看这个:SameSite浏览器版本支援 ,似乎对老浏览器的支援度不够啊。

    总结:

    道高一尺魔高一丈,还有更多的开发者与CSRF的斗法场景,比如Amazon的双cookie策略。客户端的双提交cookie等等。在这起到一个抛砖引玉的作用,keep moving

  • 相关阅读:
    GEE:使用中文做变量和函数名写GEE代码
    pta数据结构day9
    图解LeetCode——面试题 01.08. 零矩阵(难度:中等)
    Hystrix 如何在不引入 Archaius 的前提下实现动态配置更新
    【Node】使用Node.js构建简单的静态页面生成器
    多视图几何(运动恢复结构sfm)---欧式结构只能获取和世界等比例的点云,这个地方可以解决项目之中的斜率问题,但是不能够解决实际高度的问题。
    PYTHON 自动化办公:更改图片后缀
    【产品安全平台】上海道宁与Cybellum将整个产品安全工作流程整合到一个专用平台中,保持构建的互联产品的网络安全和网络合规性
    Selenium增加Chrome稳定性的参数
    解读ESSumm: Extractive Speech Summarization from Untranscribed Meeting
  • 原文地址:https://blog.csdn.net/qq_45963949/article/details/127678781