最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 如何保证网站执行的 JS 就是你想执行的 JS?

    正文概述 掘金(郑昊川)   2021-05-05   606

    背景

    我网站执行的 JS 当然是我自己写的 JS 呀,难不成还有安全问题??但想想,很多时候网站的 JS 是从第三方的 CDN 服务加载下来的,如果CDN服务器受到了攻击,JS 文件被篡改,就会带来安全风险,如何保证我们网站运行的这些脚本文件是未被修改的呢?

    还有一种情况就是 html 中可能有一些 inline script,这些 JS 可能是在服务端渲染 html 模版的时候注入的,如果网络传输过程中被抓包篡改了怎么办?

    伪代码:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
      </head>
      <body>
        <!-- inject-placeholader -->
        <div id="root"></div>
      </body>
    </html>
    
    
    router.get("/", async (ctx) => {
      const htmlTpl = await getHtmlTpl();
      const script = `window.__SOME_DATA__ = ${JSON.stringify(__SOME_DATA__)};`;
      ctx.type = "html";
      ctx.body = htmlTpl.replace("<!-- inject-placeholader -->", `<script>${script}</script>`);
    });
    

    先来看看传统软件是怎么保证用户获取到的内容是未篡改的。比如 linuxkit/linuxkit,他的发布页面会附上 Checksums

    如何保证网站执行的 JS 就是你想执行的 JS?

    这些 hash 值是根据文件内容,通过固定的算法得到的,比如上面的 SHA256。这样获取到文件的用户用同样的算法做一次计算,如果得到的 hash 值和作者标明的一致,就可以验证软件没有被别人篡改过的。

    回到前端,前端有没有类似的安全方案呢?答案是肯定的。

    1. Subresource Integrity(SRI)

    我们给 <script><link> 标签添加 integrity 属性,属性值是根据文件内容做 hash 算法得到的一个字符串。形如:

    <link href="//somecdn.com/foo.css" rel="stylesheet" integrity="sha256-t7Z7PgokIxRooJ8azMRTqZZIdgaQX6ViGg3pn3pxZZs= sha384-KJi9xVfT8JzG/tFq6Dpgw6URtNE3WK83VaQOWpfHsVAN6Az5+AjliGZuSiiWd4ah" crossorigin="anonymous">
    
    <script src="//somecdn.com/bar.js" integrity="sha256-XXVAhVe8STxZbyQhPOwZpZmx3X9iHnnrBPHUN/4vooc= sha384-438vOegRAvOckkDAIIIL8+k0JhRCRfY7Q2QXLjgFOHQbhyFK/YwGIDJBxYCdaHjA" crossorigin="anonymous"></script>
    

    其中的 sha256sha384 是 hash 算法,而 sha256-sha384- 后面的部分是 hash code, 对于跨域的脚本请求,脚本服务器需要设置 CORS 响应头,允许跨域站点访问他的内容 Access-Control-Allow-Origin: *<script><link> 标签上也需要添加 crossorigin 属性,anonymous 代表请求不携带 cookie。

    对于设置了 SRI 的脚本或样式,浏览器会对请求下载的文件内容做同样的 hash 算法,如果 hash code 不匹配,就会拒绝执行。 如何保证网站执行的 JS 就是你想执行的 JS?

    webpack 的项目可以通过 webpack-subresource-integrity 在打包时自动添加 Integrity 和 anonymous,配置如图:

    如何保证网站执行的 JS 就是你想执行的 JS? 如何保证网站执行的 JS 就是你想执行的 JS?

    2. Content-Security-Policy (CSP)

    对于一些行内脚本,我们可以通过设置 CSP 的 方式来校验。比如:

    router.get("/", async (ctx) => {
      const htmlTpl = await getHtmlTpl();
      const script = `window.__SOME_DATA__ = ${JSON.stringify(__SOME_DATA__)};`;
      const hash = require("crypto").createHash("sha256").update(script).digest("base64");
      ctx.set("Content-Security-Policy", `script-src 'self' 'sha256-${hash}'`);
      ctx.type = "html";
      ctx.body = htmlTpl.replace("<!-- inject-placeholader -->", `<script>${script}</script>`);
    });
    

    上面的 CSP 设置保证了只有 hash 值和我们给定的 hash 值一致 inline-script 才会被执行,对于不符合的 inline-script,会抛出如下错误:

    如何保证网站执行的 JS 就是你想执行的 JS?

    不过话说回来,既然算法是固定的,交付 hash code 的过程也是通过网络传输到前端的(html 内容,response header),如果有人能在网络传输的过程中修改响应,那么他把恶意代码做一次同样的算法,然后把 hash code 也改掉,还是无法避免不安全脚本的出现。这就要求我们要保证网络传输的安全。一方面我们需要给网站配置 https 避免明文传输,另一方面也要告知用户不要在访问网站的时候使用不可信代理。

    补充

    顺便说一下,保证内容可靠性的另一种常见做法。对接过微信公众号消息的同学可能有印象,微信的服务器会给我们的服务器推送消息,我们如何保证消息是微信的服务器发送过来的,而不是其他人伪造的呢?做法就是微信和我们自己的服务器都持有同一个 Token。微信发过来的消息中有一个签名 signature,这个签名就是由请求的内容和这个 Token 共同参与生成的。只要保证微信侧和我们自己的服务持有同一个Token,对同样的内容,做同样算法的签名就可以,如果最终得到的签名一致就说明请求确实是微信发给我们的。可以参考我之前写过的 Node.js 对接微信消息通知的 示例。

    如何保证网站执行的 JS 就是你想执行的 JS?

    这种做法不同于上面的一点是双方都保留了一个不为第三方所知的 Token,只要 Token 没泄露,即使别人知道你们的签名算法是啥,也无法伪造出一个签名。这种方式并不适用于前端,因为前端无法不通过网络把一个 “Token” 预先埋在所有用户的系统里。

    参考链接

    developer.mozilla.org/en-US/docs/…

    developer.mozilla.org/zh-CN/docs/…

    github.com/waysact/web…

    webpack.js.org/configurati…

    developer.mozilla.org/en-US/docs/…


    起源地下载网 » 如何保证网站执行的 JS 就是你想执行的 JS?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元