web-dev-qa-db-ja.com

ユーザー指定のURLを使用して<img>タグを安全に埋め込むにはどうすればよいですか?

仮にユーザーが次のような任意のURLからアバターを使用できるようにしたいとします。

<img class="avatar" src="{user input}" />

私が考えることができる多くの問題があります:

  • がある data urisしたがって、自己完結型のPDFファイルを作成できる可能性があります。これは実際に<img /> 鬼ごっこ?
  • javascript:表記<a />要素
  • サーバーが401無許可で応答し、基本認証を要求する可能性があり、ユーザーは自分のユーザー/パスワードの組み合わせを試すように誘惑されます
  • サーバーが巨大な画像を返す場合がある

そしておそらくもっともっと。

実際にそのイメージをダウンロードして提供せずに安全にする方法はありますか?

8
siergiej

サイトへの攻撃を回避する

受け取った文字列が有効であることを確認する必要があります。この原則を覚えておいてください。受け入れられない文字列をブラックリストにするのではなく、受け入れられる文字列をホワイトリストに入れる必要があります。

  1. 文字列が構文的に正しくエスケープされたURLであることを確認してください。 URL全体をエスケープすると、サイトの構文を破壊する可能性のある "または>が含まれなくなります。
  2. ディレクトリトラバーサル攻撃 を回避するために、URLが絶対であることを確認してください。また、Webサーバーが/var/wwwフォルダー内からアクセス可能なシンボリックリンクを処理する方法、およびサーバーが親ディレクトリへの参照を使用して絶対URLを解決する方法を理解する必要もあります。 www.server.com/../../../etc/passwd
  3. URLが、その影響を理解している既知のサポートされているプロトコル(httpまたはhttps)を使用していることを確認してください。 ¹

ユーザーのプライバシーを保護する

知らないうちにリンクを提供したユーザーはいつでもファイルを変更できるため、実際に指しているファイルが何であるかを確認しても、アプリオリな意味はありません。そのコードがブラウザーのレンダリングルーチンでバグをトリガーすると、サイトをレンダリングする(サンドボックス化された)ブラウザープロセスが危険にさらされます。

イメージを使用して、自分のユーザーのIPアドレスを収集できることに注意してください。攻撃者は、サイトに使用した画像を照会するIPアドレスを待機して収集するだけです。

401攻撃は今では修正されるはずですが、一部のブラウザではまだ適切に処理されない可能性があります。これは StackExchangeスレッド で説明されています。 this Chromeバグ追跡スレッド のように、Chromeは画像が401エラーをトリガーしたときに認証プロンプトを表示しなくなりました。

これらの2つの脅威に対する一般的な解決策があります:イメージをダウンロードしてキャッシュします。それをする余裕があれば、ユーザーが安全であるという確信が高まります。 それはあなたが求めているものではないことを知っていますが、それはあなたの最善の行動方針です

サーバーへの攻撃を回避する!

画像をキャッシュしているので、もう一度ホワイトリストに登録する必要があります。

  1. 画像がサポートされているファイル形式のいずれかに対応していることを確認してください(例:PNG/SVG/JPG/GIF)
  2. 画像が構文的に正しいことを確認してください
  3. 画像の表示に関連する情報を抽出し、認識できない、または必要としない情報をダンプすることで画像を再構成します-たとえば SVGファイルはJavaScriptを埋め込むことができるとされています ブラウザによってドメイン内で実行されます。 ²
  4. 画像の解像度とファイルサイズに適切な制限を課す

an攻撃者がfile:///some/user/secret/on/their/local/machineなどを実行できることが指摘されています。ファイルを取得せず、URLをそのままにした場合、サイトをレンダリングするレンダリングプロセスによってファイルが読み込まれる可能性があります。レンダリングのバグを悪用する画像へのsecondURLと組み合わせて、攻撃者はこのファイルのコンテンツを取得する可能性があります。

² SVGファイルは特に危険です であり、現在それらをフィルタリングするための利用可能なツールがないことに注意してください。

4