flawopen.com/XSS/SVG アップロード
SVG アップロードは XSS のリスクになりますか?
リファレンスページ
要点
アップロードされた SVG は単なるピクセルではなく文書であり、スクリプトやイベントハンドラーなどのアクティブ要素を含められます。実行の可否はブラウザーでの表示コンテキストに依存します。<img> は制限された画像コンテキストですが、インライン、直接表示、文書としての埋め込みはアクティブになり得ます。
SVG が他の画像形式と異なる点
PNG や JPEG と異なり、SVG はアクティブコンテンツを含み得る XML です。ブラウザーは <img> など制限された画像コンテキストではスクリプトを無効にしますが、直接表示、<object>、<iframe>、<embed> で文書として埋め込む場合や、マークアップをインライン挿入する場合は異なります。アプリケーション自身の origin でアクティブな文書として配信すると、プロフィール画像が stored XSS になる可能性があります。挙動はコンテキスト依存であり、拡張子や MIME はサニタイズではありません。
アップロードを安全に扱う
- ✓保存・表示前に、保守された SVG 専用サニタイザーと明示的 allowlist を使う。必要がなければ実行要素、イベントハンドラー、外部参照、
foreignObjectを除去します。正規表現で XML をサニタイズしないでください。 - ✓画像としてしか使わない場合は、分離されリソース制限されたプロセスで SVG をラスタライズし、ラスタ画像を配信します。不要なら元ファイルを web root 外に置きます。
- ✓アップロードをアプリ Cookie が送られない別の登録可能ドメインで配信します。兄弟サブドメインだけでは親ドメイン Cookie を受け取る場合があります。
- ✓未信頼 SVG を文書として残す場合は、Content-Disposition: attachment と
X-Content-Type-Options: nosniffでダウンロードを強制するか、<img> など制限された画像コンテキストだけで表示します。インライン、<object>、<iframe>、同一 origin での文書配信は避けます。
よくある質問
拡張子や MIME タイプの検証だけで十分ですか?
['拡張子や MIME タイプの検証だけで十分ですか?', 'いいえ。拡張子と宣言された MIME はメタデータであり、アクティブコンテンツの検証ではありません。実際の形式を確認し、SVG 用 allowlist で無害化するか、SVG 機能が不要ならラスタ形式へ変換します。']