Lilly
(Lillian )
1
我最近配置了 Cloudflare R2 上传存储桶,结果聊天缩略图显示异常。于是我深入排查并快速修复了配置,随后发现了这个主题:https://meta.discourse.org/t/cloudflare-r2-image-url-display-issue-detailed-explanation-and-fix/358204。无论如何,我查看了其他 S3 上传存储桶的配置,发现这个问题并非 Cloudflare 特有。
描述
当为上传配置了外部 S3 或兼容的对象存储时,聊天缩略图会绕过 CDN,直接从存储桶 URL 加载。
对于像 Cloudflare R2 这样需要安全配置的外部 S3 兼容存储桶,聊天缩略图会损坏且无法显示。
根本问题在于聊天序列化器未能将 s3_cdn_url 设置应用于缩略图。图像未通过配置的 CDN 进行路由,而是将原始的 S3 存储桶内部 URL 直接泄露到了浏览器负载中。
复现步骤
在 Meta 及其他使用 S3 上传存储桶的站点上均可复现此问题:
- 在聊天或频道中发布一张图片
- 在控制台检查缩略图图片的 URL
- 点击图片以获取更大的原图,并检查其 URL
- 将其与缩略图 URL 进行对比
以下是来自 Meta 聊天的示例:
缩略图 URL:来自存储桶
https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/meta/optimized/4X/4/7/9/479815360e0e6e0cd9f4ba565891776e84aea532_2_375x500.jpeg
原图 URL:通过 CDN
https://global.discourse-cdn.com/meta/original/4X/4/7/9/479815360e0e6e0cd9f4ba565891776e84aea532.jpeg
在控制台中,缩略图的 HTML 代码 <img... 包含 data-large-src(CloudFront CDN URL)和 src(AWS 存储桶 URL)。
截图
影响:
- 对于像 Cloudflare R2 这样默认安全且阻止未授权访问原始存储桶端点的 S3 兼容存储,聊天缩略图(优化后的)会损坏。
- 对于允许访问原始存储桶端点的 AWS 及其他 S3 兼容对象存储桶,会导致带宽泄露,因为聊天完全绕过了 CDN;这将导致为所有聊天缩略图流量支付直接的 S3 出站费用。
- 基础设施泄露:原始后端存储 URL(包括内部存储桶名称,有时甚至包括账户 ID)正被暴露在客户端 JSON 负载中。
拉取请求(PR):
我提交了一个修复该问题的 PR:
看起来 Sam 添加了 getURLWithCDN 到聊天编辑器预览中——不过,我认为它并没有应用到聊天流中?
我想知道编辑器的修复是否在某些 S3 配置下也失败了,因为 getURLWithCDN 在协议不匹配(// 与 https://)时会崩溃?无论如何,上述 PR 通过为聊天流添加包装器并使其与协议无关,扩展了 Sam 的工作。
临时解决方案:
在我意识到这不仅仅是 Cloudflare 的问题之前,我制作了一个轻量级的主题组件。它在浏览器尝试下载之前,拦截聊天 DOM 中的原始 S3 域名,并将其替换为正确的 CDN 域名。这正确地路由了流量并堵住了带宽泄露的漏洞。我对其进行了适配,使其适用于任何 S3 兼容的对象存储。只需两个设置——「原始 S3 存储桶 URL」和「S3 CDN URL」。
(不知道为什么 GitHub 的自动链接在这里失效了) 现已修复
2 个赞