美文网首页
前端安全问题实战

前端安全问题实战

作者: 般犀 | 来源:发表于2020-08-16 19:15 被阅读0次

    之前公司的安全组扫出了我们官网的几个安全漏洞。安全问题对很多前端来说都是只听过,没见过。这次遇到了真实对漏洞,可以做个记录。

    存储型XSS漏洞

    XSS,跨站脚本攻击。存储型XSS攻击,即攻击代码被当成文本(如帖子)提交保存到服务器,其他用户打开这段文本的时候,代码就会在其他用户的浏览器里执行。

    场景:一个坏人在论坛发布帖子 内容如下:

    大家好,第一次在这个论坛发帖,现在我要植入一段代码:<img src=x onerror=alert(1)>
    

    如果论坛没有对帖子的内容做转义处理,直接发布出去。 其他用户点击这个帖子,页面就会插入这个图片标签。由于图片的src异常,图片加载失败,就会触发onerror里的alert。

    如果onerror里的内容不是一个简单的alert,而是一段盗取用户cookies的代码呢?那么就会对用户对账户造成威胁。

    防御措施

    对< > / 符号做escape转义即可,escape可以把所有ASCII 之外的所有字符转换为 %xx 或 %uxxxx(x表示十六进制的数字)的转义序列。

    延伸:vue 中 v-html 指令的合理使用

    用过 vue 的同学都知道,v-html 的作用是可以把填入 v-html 里的值转化为 html 代码,所以 v-html可能会成为攻击者利用的漏洞,如果把用户提交的内容使用 v-html渲染,就可能会把用户输入的内容变成可执行的代码,形成 XSS 攻击。

    反射型XSS漏洞

    反射型漏洞:攻击者通过特定的方式来诱惑受害者去访问一个包含恶意代码的URL。
    场景还是坏人在论坛发帖,坏人在帖子里贴一个URL,其他用户访问这个URL,使URL上的代码在用户浏览器里被执行。
    可能有人会问,在帖子里附带链接不是正常现象吗,用户点击第三方链接导致被攻击跟我有什么关系?
    那么,如果用户点击的就是官方链接而触发了XSS攻击呢?

    场景:这个发生场景现在来看有点古老了,但大部分网站可能仍会使用的跨域策略:JSONP。
    简单描述JSONP的流程:前端使用<script>标签请求后端资源,后端返回的资源会被一个函数包裹,类似:

    callback({
      a: 1,
      b: 2
    });
    

    而前端会提前在页面定义好这个callback函数,例如:

    // 请求到达页面,触发 callback 函数,将资源挂到window上
    function callback(res) {
      window.res = res;
    }
    

    而通常后台返回的函数名并不会固定返回callback,因为可能会调用到页面其他叫callback的函数,所以,前端在请求的时候,都会在链接后带一个参数,告诉后台,返回的函数名应该叫什么,例如:

    前端请求地址:https://xxxxx/giftjson?jsoncallback=mycallback
    后台返回结果:

    // jsoncallback传的参数是什么,返回的函数名就是什么
    mycallback({
      a: 1,
      b: 2
    });
    

    可以看到,请求地址上的jsoncallback参数是什么,后台返回的函数名就是什么。看到这句话是不是隐隐感觉到不对劲?如果jsoncallback参数是一段代码呢?

    假设,坏人发现了斗鱼直播的一个接口有这个漏洞,在斗鱼论坛发帖:

    斗鱼出了个活动啦,大家点击这个链接可以免费抽奖,这个是斗鱼官方链接大家放心点:
    https://www.douyu.com/getUserInfo?jsoncallback=<img+src=x+onerror=alert(1)>
    

    其他用户发现这个确实是斗鱼的官方链接就点了进去,结果就运行了jsoncallback里的代码。

    防御措施

    个攻击其实还需要一点机缘巧合,比如把返回头的Content-Type设置成了application/javascript或者text/html,就会导致字符被当作代码运行。所以防止反射型攻击的方法就是将返回头的Content-Type设置为application/json;即可。

    CSRF 攻击

    CSRF,跨站点请求伪造。即攻击者在他自己的网站调用你的接口,达到修改你的网站数据的目的。

    场景:用户在斗鱼论坛设置了“记住我的登录状态”,于是 douyu.com这个域名下保存了用户的登录cookies。攻击者注意到斗鱼修改用户资料的接口douyu.com/updateUserInfo有CSRF漏洞,于是他伪造了一个斗鱼论坛网站,并做了一个表单:

    <html>
    <body>
        <form id="csrf" action="douyu.com/updateUserInfo" method="POST">
            <input type="hidden" name="gender" value="2" />
            <input type="hidden" name="hometown" value="1234" />
            <input type="hidden" name="birthday" value="2020&#45;06&#45;11" />
            <input type="hidden" name="nick&#95;name" value="1234" />
            <input type="hidden" name="st" value="123" />
            
        </form>
    </body>
    <script type="text/javascript">
        function autoSubmit() {
            document.getElementById("csrf").submit();
        }
        autoSubmit()
    </script>
    </html>
    

    这个表单会提交到douyu.com/updateUserInfo接口,由于用户的浏览器保存了登录的cookies,请求发送出去的时候,用户的登录态也会带出去,斗鱼验证登录态后,确认了是用户本人操作,允许了本次修改。

    我们可以发现,通过CSRF漏洞,攻击者伪造了用户的登录态,使修改用户资料的操作成功了。如果本次操作不是修改用户操作,而是转账等危害用户资产安全的操作呢?

    防御措施

    由此可见,涉及资料修改的操作,仅验证用户登录态是不够的。还需要其他的验证手段:

    初级防御措施:判断请求的Referer

    请求中的Referer头用于判断该请求是在哪个页面的基础上发出去的,比如a.com请求了一张图片douyu.com/1.jpg,那么图片的Referer头就为:Referer: a.com
    上面的攻击场景中,服务器可以判断请求的Referer头,判断该请求是否是官方网站douyu.com发出的,如果不是,则说明是第三方调用,禁止修改。
    但是问题是,请求的请求头是可以修改的,攻击者只要将请求的Referer头手动修改为douyu.com,就绕过了这层防御。

    进阶防御措施:

    1. token校验
      每个修改资料的请求,都必须携带一个token,而这个token只能在官方网站下生成,提交修改操作的时候,校验这个token是否正确,只有正确才允许修改资料。
      这种验证又叫做“加盐”验证。在表单中混入一个做校验的表单项,用来给服务器做安全校验。

    2. cookies设置Samesite
      设置保存登录态的 cookies 只能在同一个域名的页面下才会随着请求一起发送。这样可以保证cookies不会被第三方使用。但是也多了一个束缚是登录态不能被其他我们受信任的域名共享。
      比如很多单点登录的实现(即如果你在taobao.com登录了,你访问tmall.com的时候,会发现也是登录着的)就是基于 cookies 共享,可能就会收到影响。

    相关文章

      网友评论

          本文标题:前端安全问题实战

          本文链接:https://www.haomeiwen.com/subject/rqxxjktx.html