ファイルアップローダーのファイル名の出力箇所はエスケープしなくても良いか?


確かにWindowsではファイル名に「\、/、:、*、?、”、<、>、|」といった文字を使うのを禁止しておりこれらの文字列が使えない状況でXSSを引き起こすのはほぼ無理でしょう。

スクリーンショット 2015-02-01 23.21.48

しかし、*nix系のOSではファイル名にこれらの文字を使用することが可能です。
実際私の使っているMacでも以下の様なファイル名のファイルを作成することが出来ます。

スクリーンショット 2015-02-01 23.23.17

ここからXSSの話です。
例えば以下の様なファイルアップロードのPHPコードがあるとします。
[php]
<?php
if($_FILES["file"]["error"] > 0){
echo "Error:".$_FILES["file"]["error"]."<br/>";
}else{
echo "Upload:".$_FILES["file"]["name"]."<br/>";
}
?>
<html>
<body>
<form action="" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>
[/php]

このプログラムは以下のようにファイルのアップロードを受け付けます。

スクリーンショット 2015-02-01 23.33.55

このサイトに先ほど作ったファイル名にスクリプトが動作する文字列が含まれたファイルをアップロードしてみます。

スクリーンショット 2015-02-01 23.35.16

アラートが表示されました。
このファイル名が今後もこのページに残る、といった仕様の場合は蓄積型XSSとなってかなりクリティカルな脆弱性となります。

「わざわざ*nix系でファイル名にタグ入れなくてもfiddlerとかで書き換えればいいじゃん」っていうのは今回はナシでお願いします(懇願)