チャットのサムネイルが s3_cdn_url をバイパスし、生きた S3 バケット URL を使用

, ,

最近、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 アップロードバケットを使用しているサイトでも再現可能です:

  1. チャットまたはチャンネルに画像を投稿する
  2. コンソールでサムネイル画像の URL を確認する
  3. 画像をクリックして元の大きな画像を表示し、URL を確認する
  4. サムネイルと比較する

以下は 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 を追加したようですが(Upload images in chat can't be show normally when use s3 CDN - #15 by sam

プロトコルの不一致(//https://)で getURLWithCDN がクラッシュするため、コンポーザーの修正が一部の S3 設定で失敗していた可能性もあるかもしれません。いずれにせよ、上記の PR は Sam の作業を拡張し、ストリームにラッパーを追加してプロトコル非依存にすることで対応しています。

一時的な回避策:

これが Cloudflare 固有の問題以上であることを理解する前に、軽量なテーマコンポーネントを作成しました。これは Chat DOM 内の生 S3 ドメインをインターセプトし、ブラウザがダウンロードを試みる前に適切な CDN ドメインに置き換えます。これにより、トラフィックが正しくルーティングされ、帯域幅の漏洩が解消されます。これを任意の S3 互換オブジェクトストレージで動作するように適応させました。設定は「Raw S3 バケット URL」と「S3 CDN URL」の 2 つだけです。

(なぜか GitHub のワンボックスがここで壊れていましたが) 現在修正済み

「いいね!」 2

おそらくサイトの移動に関連しているでしょう……私は今すぐ再焼きしました。

「いいね!」 1