V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
raw0xff
V2EX  ›  JavaScript

cloudflare workers 传入网页时注入脚本的话,是不是服务端设置 CSP 也没办法保证完整性?

  •  1
     
  •   raw0xff · 2024-04-07 23:21:07 +08:00 · 2261 次点击
    这是一个创建于 369 天前的主题,其中的信息可能已经有所发展或是发生改变。

    域名 DNS 都在 cloudflare 内管理,worker.js 可以在获取服务端内容后修改然后再发给客户端,那岂不是可以轻易绕过 CSP ?作为服务端网页如何保证自己完整性?

    25 条回复    2024-06-06 10:05:37 +08:00
    codehz
        1
    codehz  
       2024-04-08 00:01:50 +08:00 via iPhone
    这不都是你自己管理的东西吗,csp 防止的是未授权的修改,不是防止你在你自己域名上的授权修改
    ETiV
        2
    ETiV  
       2024-04-08 00:26:48 +08:00 via iPhone
    能改的只有 worker 和 cloudflare ,worker 你自己控制,cloudflare 靠商誉不去修改你的东西…

    有种 Notion page 自定义域名的做法就是代理然后靠 worker 修改请求下来的所有资源里的 notion 的域名…我不知道现在还好使不,如果不灵了你可以了解下 Notion 是怎么做的…如果还能用,那说明 Notion 也没辙……
    raw0xff
        3
    raw0xff  
    OP
       2024-04-08 00:55:07 +08:00 via iPhone
    @codehz 主机运行的服务端与主机及域名权限拥有者不是一个人。担心主机通过 worker 注入代码,浏览器得到的网页代码被修改,用户操作就不安全。


    @ETiV 理论上 worker 能完整的得到响应就能改,貌似无解。不知道服务端是否能分辨出请求是否来自 worker 还是客户端浏览器?
    caomingjun
        4
    caomingjun  
       2024-04-08 00:59:56 +08:00 via Android   ❤️ 1
    raw0xff
        5
    raw0xff  
    OP
       2024-04-08 01:06:40 +08:00 via iPhone
    @caomingjun 常规是有标识,但是 worker 可以修改 fetch 的 headers ,可以伪装成普通浏览器用户。
    caomingjun
        6
    caomingjun  
       2024-04-08 01:13:15 +08:00 via Android
    @raw0xff 据我所知应该是改不了的,你不放心可以试试。普通用户倒是可能加个 header 伪装成 worker 。
    icoming
        7
    icoming  
       2024-04-08 01:19:21 +08:00
    @caomingjun 楼主不是你这个意思,你是说服务端可以识别到请求来自 cf worker ,然后处理。但是楼主是说他知道请求来自 worker ,只是想保证经过 worker 后,客户端收到的是没有修改中间端修改过的响应

    其实这和 worker 没什么关系,直接搜索客户端数据校验之类的看看
    ETiV
        8
    ETiV  
       2024-04-08 01:33:31 +08:00 via iPhone
    @icoming 但是 worker 作为一个完美的中间人,校验函数都可以给改掉…😂 可以说是为所欲为了
    raw0xff
        9
    raw0xff  
    OP
       2024-04-08 01:55:18 +08:00 via iPhone
    @caomingjun 标头都可以修改


    @icoming
    @ETiV
    完美中间人形容很贴切。不知道页面嵌入个 wasm 能不能解决问题。或者就换个思路,模拟普通用户访问对网页代码进行验证。
    r46mht
        10
    r46mht  
       2024-04-08 03:25:59 +08:00 via Android
    现成的解法是不是上面再加一层 tls
    geekvcn
        11
    geekvcn  
       2024-04-08 05:00:01 +08:00 via Android
    现在市面上所有 CDN 都是一个天然中间人,甚至还有你的域名证书,想干啥就能干啥,信得过就用,信不过就别用。
    raw0xff
        12
    raw0xff  
    OP
       2024-04-08 09:36:02 +08:00 via iPhone
    @r46mht 不是,加 tls 的话证书和 key 都是暴露的,无济于事。

    为了确保 worker 不注入代码,浏览器收到的是服务端给的完整代码。
    CSP 不行,会被直接绕开。
    服务端识别请求也不行,worker 可以修改标头。

    如果服务端对每次每个用户的登录请求返回不同的内容(比如随机函数名随机变量名随机代码排序等等)使中间人统一作恶有一定难度,不知道这个想法成不成熟有没有用。

    在这种带证书的中间人情况下,是不是任何措施都只能增加中间人作恶难度,而不能解决根本问题? 哪位老哥给点建议,不行我就换个思路,定期从外部访问校验网页是否安全。
    0o0O0o0O0o
        13
    0o0O0o0O0o  
       2024-04-08 11:33:17 +08:00
    我确定我看了你的每一句话,但我仍然要靠猜去理解你的需求,所以是:
    1. 你无法控制域名和 cloudflare workers
    2. “主机运行的服务端” 是你的
    3. 你希望用户能收到没被篡改的来自“主机运行的服务端”的内容

    如果是这样,那就无解,客户端就算要校验,你也需要保证客户端网页源码可信,由于 1 的存在,你无法保证。我能想到的就是你通过自己的渠道分发客户端,只是调用 cloudflare workers 来获取需要的数据,这时你就可以校验了。
    raw0xff
        14
    raw0xff  
    OP
       2024-04-08 18:46:10 +08:00
    @caomingjun worker.js 里可以改 response 中所用东西,试过了。


    @0o0O0o0O0o 感谢大佬这么细致,你猜的对,“当自己的 web 应用跑在别人的主机和域名下,如何避免网页被注入”。感觉只能制造注入控制的难度,治标不治本。比如整个随机变量名和随机位置啥的。另外浏览器加载网页 js 后是需要跟服务端程序通信的,我总觉得有办法解决,又想不出办法。
    0o0O0o0O0o
        15
    0o0O0o0O0o  
       2024-04-08 19:57:16 +08:00
    @raw0xff #14 可以参考这里的讨论: https://news.ycombinator.com/item?id=39436238 我觉得算同类问题,所以如果你坚持是浏览器里访问的网页应用,那目前就是没有办法解决的
    raw0xff
        16
    raw0xff  
    OP
       2024-04-08 20:33:55 +08:00
    @0o0O0o0O0o 感谢大佬,真巧重合度很高,文中说的方式试过一些,CSP SRI IPFS 再叠上一些加密方式的 buff 。但是没有一个完美的解决方案。
    raw0xff
        17
    raw0xff  
    OP
       2024-04-08 21:10:13 +08:00
    @0o0O0o0O0o 服务端应用给每次请求登录时的页面内包含随机值且记录下来,登录时 js 将自己的网页 hash 一并发给服务端,服务端验证 hash 后再进行登录验证。 大佬帮忙看这逻辑有没有漏洞?
    r46mht
        18
    r46mht  
       2024-04-08 22:19:24 +08:00
    @raw0xff 我的意思是理论上你可能可以这样:

    1. 搞一个自签名证书,把自签名证书放到你的服务器里
    2. host 一个静态网页,你需要确保用户收到的这个静态网页是完整的。
    3. 这个静态网页包含一段包含了 tls 实现的 JavaScript 代码
    4. 这段代码会开一个 websocket 连接到你的服务器,并且跟你的服务器完成 tls 握手。在握手的时候这段代码会校验连接的另一头是不是有你的自签名证书。
    5. 现在你可以放心大胆的通过这个 websocket 传输 worker 不可解密的数据了!
    0o0O0o0O0o
        19
    0o0O0o0O0o  
       2024-04-08 22:28:14 +08:00
    @raw0xff #17 你的场景中,你服务端收到的任何数据都不可信,中间人都可以随意篡改。
    raw0xff
        20
    raw0xff  
    OP
       2024-04-08 22:42:16 +08:00
    @r46mht
    感谢回答。问题就出在你说的静态网页上,也就是说无法保证用户访问的第一个网页的完整性。如果可以的话,后续任何代码变动都可以被 csp 和 sri 约束。
    15 楼给的链接 https://news.ycombinator.com/item?id=39436238 里有讨论到。
    raw0xff
        21
    raw0xff  
    OP
       2024-04-08 23:11:28 +08:00
    @0o0O0o0O0o 好像真的无解,即便关键代码写成 wasm 也没啥用。
    raw0xff
        22
    raw0xff  
    OP
       361 天前
    @caomingjun 对不起,你是对的,标头可以修改,但是返回给浏览器前 cloudflare 会重新改回来。所以网站是否用了 worker 是可以从响应头分辨的。
    forty
        23
    forty  
       319 天前
    很简单,把验证信息放入另一个不经过 cloudflare 的域名站点。
    主体内容走 cf, 验证信息走另外通道。
    raw0xff
        24
    raw0xff  
    OP
       310 天前
    @0o0O0o0O0o 大佬方便飞机向您求教吗?

    我的 rsa 公钥

    -----BEGIN RSA PUBLIC KEY-----
    MIGJAoGBALJxVGJhfs6tY1kKUl9y4k/5qXoYTn+/mS8keK9CmzvyPJ63hF7HHG37
    ZaLCNZIWrUf2dwtepuXVf40H+SAsRMDMy4/BRlovlqSIClGudAuCVVOxelNoQ3Sc
    nKiyPjPmlbkBJVL1JclXq17g8p5SlBmGeePCM7/75J8uTuarboxDAgMBAAE=
    -----END RSA PUBLIC KEY-----

    https://try8.cn/tool/cipher/rsa
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2693 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 11:18 · PVG 19:18 · LAX 04:18 · JFK 07:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.