ファイルダウンロードによるXSS その1
発生箇所 | ファイルのアップロード機能、ダウンロード機能 |
---|---|
影響を受けるページ | アプリケーション全体。特にセッション管理や認証のあるページは影響が大きい |
影響の種類 | 成りすまし |
利用者の関与の度合い | 必要。リンクのクリックなど |
概要
アップロードしたファイルを利用者がダウンロードする際に、ブラウザがファイルタイプを誤認する場合がある。例えばアプリケーションがPNG画像を想定しているにもかかわらず画像のデータ中にHTMLタグが含まれていると、条件によってはブラウザがHTMLファいつと誤認して、画像ファイルに埋め込まれたらJavaScriptを実行する場合がある。これがファイルダウンロードによるXSSである。
この脆弱性を悪用する攻撃者はHTMLやJavaScriptを仕込んだ画像ファイルやPDFファイルをアップロードして公開する。このファイルは通常の参照の仕方ではHTMLとは認識されないが、攻撃者がアプリケーション利用者に罠を仕掛けてアップロードしたファイルがHTMLとして認識されるように仕向ける。ブラウザがこのファイルをHTMLとして認識するとXSS攻撃が成立する。
攻撃手法
攻撃手法を2例示す。いずれもIE以外のブラウザでは必ずしも再現しない。
●画像ファイルによるXSS
画像ファイルに偽装したファイルにHTMLやJavaScriptを仕込んだものをアップロードする方法によってXSS攻撃が可能となる場合がある。画像によるXSSはIE8以降では対策されている。
アップロードファイルによるサーバ側スクリプト実行の記事のスクリプト実行対策版アップローダでsample.pngというファイルをアップロードする。このファイルは拡張子はpngだが内容は以下のスクリプトである。
<script>alert('XSS');</script>
アップロード完了の画面において、img要素の部分は×印となる。リンクをクリックするとIE7では上記のJavaScriptが実行される。IE8ではスクリプトがテキストとして表示される。
実際の攻撃では攻撃用のJavaScriptを仕込んだファイルを画像としてアップロードした上で、その画像を表示するURLを罠サイトに仕込む。ただしimg要素で画像として表示してもJavaScriptは実行されないので、iframe要素などを用いてHTMLとして表示させる。
画像ファイルによるXSSの影響は通常のXSSと同じである。すなわちクッキー値の盗み出しによる成りすまし、Web機能の悪用、画像改変によるフィッシングなどが可能である。
●PDFダウンロード画面によるXSS
次の例はPDFのようなアプリケーションファイルのダウンロードサービスを想定している。ストレージサービスを簡略化したものである。
ファイルをアップロードする画面はアップロードファイルによるサーバ側スクリプト実行の記事のものからform要素のactionだけを変更したものを使用する。
同様にファイルを受け付けるスクリプトとダウンロードスクリプトは受け付けるファイルの拡張子をpdfに変更したものを使用する。
以下にファイルを受け付けるスクリプトupload2.php(抜粋)とダウンロードスクリプトdownload2.phpである。ダウンロードスクリプトでは拡張子のチェック以外に3行目のMIMEタイプの指定部分も変更しており、PDFのContent-Typeとしては不正な値をセットしている
<?php define('UPLOADPATH', '/var/upload'); function get_upload_file_name($tofile) { // 拡張子のチェック $info = pathinfo($tofile); $ext = strtolower($info['extension']); if ($ext != 'pdf') { die('拡張子はpdfを指定ください'); } // 中略 $imgurl = 'download2.php?file=' . basename($tofile); ?> <body> <a href="<?php echo htmlspecialchars($imgurl); ?>"><?php echo htmlspecialchars($orgfile, ENT_NOQUOTES, 'UTF-8'); ?> をアップロードしました</a><br> </body>
<?php define('UPLOADPATH', '/var/upload'); $mimes = array('pdf' => 'application/x-pdf'); $file = $_GET['file']; $info = pathinfo($file); // ファイル情報の取得 $ext = strtolower($info['extension']); // 拡張子 $content_type = $mimes[$ext]; // Content-Typeの取得 if (! $content_type) { die('拡張子はpdfを指定ください'); } header('Content-Type: ' . $content_type); readfile(UPLOADPATH . '/' . basename($file)); ?>
正常なPDFファイルをアップロードするとリンクが表示され、そのリンクをクリックするとPDFファイルをダウンロードできる(ファイル名の拡張子は.pdfにならないがダウンロードされるファイルの中身はPDFである)。
攻撃の場合、例として以下のようにscript要素のみからなるHTMLファイルpdfという拡張子を持つファイル名にしてアップロードする。
<script>alert('XSS');</script>
この偽装PDFファイルをアップロードすると、正常なPDFファイルをアップロードした時と同様にリンクが表示される。リンクをクリックするとファイルダウンロードのダイアログが表示される。
ここからは、攻撃者の視点で罠のためのURLを作成する手順を説明する。ダウンロード用リンクをマウスで右クリックしてコンテキストメニューを表示し、「ショートカットのコピー」を選択する。コピーした内容は以下。
http://example.jp/download2.php?file=<ランダムな文字列>.pdf
これに下記のように「/a.html」という文字列を挿入する。挿入した文字列はPATHINFOと呼ばれるもので、見かけ上はファイル名のような形でパラメータを埋め込む方法である。a.htmlというファイルは存在しないので、パラメータとしてスクリプトに渡される。
「/a.html」を挿入した意味については次回の記事の「脆弱性の原因」で説明する。
http://example.jp/download2.php/a.html?file=<ランダムな文字列>.pdf
このURLをIEのアドレスバーに入力してEnterキーを押下するとJavaScriptが実行される。
偽装画像の場合と異なりIE8でもJavaScriptが実行される(この記事を書いている時点で最新のIE11ではJavaScriptは実行されず、PDFの中身がテキストとして表示される。
この脆弱性の根本原因はContent-Typeの間違いである。PDFの正しいContent-Typeは「application/pdf」だが、「application/x-pdf」と不正なContent-Typeを指定したことが直接的な原因である。
参考文献:体系的に学ぶWebアプリケーションの作り方 4.12.3 ファイルダウンロードによるクロスサイト・スクリプティング
![]() | 体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践 徳丸 浩 ソフトバンククリエイティブ 2011-03-03 売り上げランキング : 4070 Amazonで詳しく見る by G-Tools |
PATHINFO(PATH_INFO)について参考にしたサイト:
環境変数PATH_INFOとは? - 苔の一念岩をも通す ~目指せいつかはプログラマ~
PATH_INFOって何? - よくきたWiki
PHP: $_SERVER - Manual
« とんでもない地図の本 | Main | ファイルダウンロードによるXSS その2 »
「PHP」カテゴリの記事
- PHPStorm 2018.1.7 に更新(2018.12.09)
- PHPメモ051:includeとrequireの使い分け(2015.06.19)
- CakePHPのインストール(2015.06.14)
- PHPからPDOでPostgreSQLに接続する(2015.06.09)
- PHPでメールを送信したら一部のOutlookで受信したメールでヘッダがおかしくなった(2015.05.31)
「セキュリティ」カテゴリの記事
- PHPメモ041:パスワードのSalt付きハッシュ値(2014.08.09)
- ファイルインクルード脆弱性(2014.05.18)
- ファイルダウンロードによるXSS その3(2014.03.27)
- ファイルダウンロードによるXSS その2(2014.03.23)
- ファイルダウンロードによるXSS その1(2014.02.24)
The comments to this entry are closed.
Comments