外部画像を安全に扱う
広告配信システムを構築・運用していると、ユーザーが外部ドメインの画像(例:https://sample.com/image.jpg)を登録し、それを広告素材として使いたいという要件が発生します。
しかし、外部ドメインの画像をそのまま<img src=...>で読み込ませることは、セキュリティやプライバシーの観点から非常に危険です。本記事では、Facebookなど大手サービスが実践している安全な画像配信の設計パターンと、それをGo言語で実装する現実的な方法について、技術的に詳しく解説します。
なぜ外部画像をそのまま使ってはいけないのか?
主なリスク:
- 
マルウェア・XSS
- 
画像形式に偽装されたスクリプトや、不正なEXIF情報が仕込まれている場合があります。
 
 - 
 - 
トラッキング
- 
外部画像を読み込むと、そのサーバにユーザーのIPアドレス、User-Agent、Refererが送信されます。
 - 
Cookieも同一ドメインであれば送られますが、ドメインが異なれば送られません。
 
 - 
 - 
コンテンツ差し替え
- 
ユーザーが画像URLを登録した後に、画像の中身だけを差し替えることで、後から不適切な内容にすり替えられる可能性があります。
 
 - 
 
Facebookなどがやっていること
Facebook(Meta)は、外部画像を直接使うことはありません。すべての画像を一度自社のサーバーで検査・加工し、scontent-*.fbcdn.net などの自社CDN経由で配信します。これは以下の理由によるものです:
- 
セキュリティの確保(EXIF除去・MIMEチェック・再エンコード)
 - 
トラッキング制御(外部へのリクエストを防ぐ)
 - 
パフォーマンス最適化(CDNキャッシュ配信)
 - 
コンテンツ審査対応(広告画像審査のために内容を確定化)
 
自社で安全に外部画像を扱うには?
✅ 安全な構成案:
- 
ユーザーが外部画像URLを登録(例:
https://sample.com/img.jpg) - 
登録時 or 表示時にプロキシサーバーで:
- 
画像を一時取得(
GETorHEAD) - 
MIMEチェック、magic bytesチェック
 - 
再エンコード(Goの
image.Decode()+jpeg.Encode()など) - 
不正なEXIF・メタ情報を除去
 
 - 
 - 
再エンコード後の画像をそのままメモリで返却(ディスク保存なし)
 - 
ユーザーのブラウザには
yourdomain.com/proxy?url=...の形式で自ドメイン配信 
再エンコードとは?なぜ重要?
画像ファイルはピクセル情報だけでなく、EXIF情報やICCプロファイル、コメントセクションなどさまざまなメタデータを含みます。そこに悪意あるコードや個人情報が含まれるケースがあります。
再エンコードの利点:
- 
不要なメタ情報を全削除
 - 
マルウェアやトラッキングを除去
 - 
常に標準フォーマット(JPEG/PNG)で再生成
 
img, _, _ := image.Decode(resp.Body)         // 画像デコード
jpeg.Encode(w, img, &jpeg.Options{Quality: 85})  // 再エンコードしてレスポンス返却
差し替え検出はできるのか?
はい、外部画像の差し替えを検知する仕組みも可能です。
方法:
- 
画像URL登録時に
Last-ModifiedやETag,Content-Lengthを保存 - 
表示時にHEADリクエストで再取得
 - 
値が一致していれば表示許可、一致しなければ拒否
 
保存せずに再エンコードだけするのは現実的か?
✅ 現実的で、多くの大手サービスも採用している方法です。
この構成の利点:
| 項目 | 内容 | 
|---|---|
| セキュリティ | EXIF・不正MIME除去、XSS防止 | 
| プライバシー | 外部サーバへのIP/Cookie送信なし | 
| パフォーマンス | CDNキャッシュ活用可能(短期) | 
| シンプル性 | ストレージ管理が不要 | 
注意すべきセキュリティ対策
- 
SSRF防止(127.0.0.1やAWS内部メタデータへのアクセス制限)
 - 
サイズ制限(5MB上限など)
 - 
タイムアウト制限(5秒以内など)
 - 
MIMEとmagic bytesの整合確認(JPEGなら
FFD8FF, PNGなら89504E47) - 
自サイトへの再帰的プロキシを禁止
 
まとめ
外部画像を広告素材として安全に使うには、「プロキシ経由で画像を再取得し、無害化処理をして自ドメインから配信する」構成が最も現実的かつ安全です。
Go言語を使えば、画像の取得・解析・再エンコード・配信まで非常に効率よく処理できます。ストレージ保存なしでもこの仕組みは十分実用的で、多くの商用サービスで実践されています。
ご希望があれば、実装例やコードスニペットの提供も可能です。
登録日:
更新日: