忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2017/07/23 19:51 |
getimagesize/finfoのMIMEタイプ判定はザルい
http://qiita.com/sakana_kirai/items/6e512f7aea2898a6e8f2
http://qiita.com/mpyw/items/939964377766a54d4682

アップロードされたファイルについて、getimagesize()やfinfo::file()でMIMEタイプを判定しています。
<?php
	// hoge.pngを判定
	$imagesize = getimagesize('path/to/hoge.png');
	$finfo = new finfo(FILEINFO_MIME_TYPE);
	$finfofile = $finfo->file('path/to/hoge.png');
	var_dump($imagesize, $finfofile);
ここでhoge.pngの中身を以下のように書き換えてみます。
	GIF8<script>alert("xss");</script>
結果。
array(6) {
  [0]=>
  int(29283)
  [1]=>
  int(28777)
  [2]=>
  int(1)
  [3]=>
  string(28) "width="29283" height="28777""
  ["channels"]=>
  int(3)
  ["mime"]=>
  string(9) "image/gif"
}
string(9) "image/gif"
なんと頭に「GIF8」と書いておくだけでMIMEタイプの判定をすり抜けてしまいました。

まあMIMEタイプがimage/gifだとわかったので、ファイルは見えないところに隠しておいて、出力時にきちんとContent-Typeヘッダを出してあげれば問題ありません。
<?php
	header('Content-type: image/gif');
	readfile('path/to/hoge.png');
これで完璧!



お、おう。

これはIEでのみ発生する可能性のあるXSSです。
IEは設定されたContent-Typeをあまり気にせず、ファイルの中身を見て適切な形式で出力してくれるという素敵極まりない機能が付いています。
で、IEは「GIF8」をgifとはみなさず、後続のHTMLを見てHTMLと判断してくれやがるようです。
「GIF87」にすると画像と判断されます。

X-Content-Type-OptionsというHTTPヘッダによって、この余計で傍迷惑な機能を止めることができます。
http://d.hatena.ne.jp/hasegawayosuke/20110106/p1
http://blog.everqueue.com/chiba/2011/01/06/484/
<?php
	header('Content-type: image/gif');
	header('X-Content-Type-Options: nosniff');
	readfile('hoge.png');
これでIEでもXSSが発生しないようになります。
結果としては、とりあえずあらゆる出力にX-Content-Type-Optionsを書いとけ、というところでしょうか。

ちなみに
http://d.hatena.ne.jp/hasegawayosuke/20110106/p1
> あらゆるコンテンツのレスポンスヘッダに X-Content-Type-Options: nosniff を付与するようにしましょう

とか書いてるこのページにはX-Content-Type-Optionsが設定されていません。
PR


2014/07/04 21:54 | Comments(0) | PHP

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<買ったものリスト 2014/07/06 | HOME | Windows7でVagrantの環境整備>>
忍者ブログ[PR]