質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

4153閲覧

画像XSSがマジックバイトチェックで防げない件について

nasubi256

総合スコア18

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

2グッド

4クリップ

投稿2017/08/25 14:11

画像XSSの対策として、マジックバイトチェックがよく挙げられるのですが、
マジックバイトチェックは最初の数Byteのチェックしか行わないため、
それ以降の画像内コードにhtmlタグが紛れ込んでいたとしても、チェックに引っかかりません。

この場合のphpでの対策として、有効な方法をご教授いただけないでしょうか。
ちなみに、拡張子、Content-type、mimeタイプのチェックは既にしております。

自分では画像内コードを文字列検索する下記のような方法しか思いつけませんでした。

$nakami = file_get_contents($file_real); if (strpos($nakami, 'html') !== false) { echo 'htmlタグが入っている不正な画像です'; }else { echo '正しい画像です'; }
akakou, yohhoy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ockeghem

2017/08/26 00:43

『それ以降の画像内コードにhtmlタグが紛れ込んでいたとしても、チェックに引っかかりません。』ということですが、マジックバイトのチェックは、仮に画像内にHTMLタグがあってもブラウザにHTMLとして解釈させないようにするための施策です。<script>タグ等が画像内になっても、ブラウザに画像として認識されている状態では、XSSにはなりませんが、認識はあっていますか?
nasubi256

2017/08/29 03:54

>、ブラウザに画像として認識されている状態では、XSSにはなりませんが、認識はあっていますか? これがまさに的を得ておりました。詳しくは自己解決回答に記載させていただきました。
guest

回答3

0

ベストアンサー

画像XSSは、元々以下のようにIEの古いバージョンの仕様に起因する問題です。

  • IE7以前は、HTTPレスポンスヘッダではなく、コンテンツの中身によってContent-Typeを判定する仕様があった
  • これにより、画像の中身がHTMLっぽい場合に、Content-Typeヘッダがimageとなっていても、text/htmlと判定する場合があった
  • そのため、画像の中身にscriptタグ等を入れておくと、JavaScriptが実行できる場合があった

これは、IEの「余計なお世話」であって、さらに言えば脆弱性と言えるような仕様です。

これに対して、マイクロソフトはMS07-057の修正プログラムにより、Content-Typeが画像を示す場合で、かつマジックバイトがContent-Typeと対応する場合には、画像の中身ではなく、Content-Typeの方を優先するように仕様が変わりました。詳しくは下記のブログ記事をご覧ください。

画像ファイルによるクロスサイト・スクリプティング(XSS)傾向と対策

これを守っていれば、仮に画像の中身にHTMLタグを入れても、HTMLとは判定されず、JavaScriptの実行もされません。

さらに、最近のIEではContent-Typeの判定にコンテンツの中身を使うことはしない方向に触れていますし、maisumakun さんの指摘のように X-Content-Type-Options: nosniff まで指定すれば、確実に、コンテンツの中身には関係なくContent-Typeを優先するはずです。

なので、「画像XSSがマジックバイトチェックで防げない」というのは誤解ではないかと思うのですが、いかがでしょうか?

投稿2017/08/26 07:43

編集2017/08/26 08:29
ockeghem

総合スコア11701

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nasubi256

2017/08/29 03:53

丁寧なご回答ありがとうございました。結局の問題がこのご回答以前の問題だったのがお恥ずかしい限りです。
guest

0

今時はブラウザ側の対策も進んでいますので、逆に画像XSSが現実的な脅威となるのかが気になります。

X-Content-Type-Options: nosniffMDN)とした上で、画像として正しいContent-typeをセットすれば、IE8でもHTMLとしての解釈は行われません。

投稿2017/08/25 14:25

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nasubi256

2017/08/29 03:52

簡潔なご回答、ありがとうございました!
guest

0

お恥ずかしい話ですが、
そもそものレスポンス指定が問題で、画像がhtmlとして認識されてしまっていたことが問題でした。

具体的には、laravelで下記のように指定すると、指定したcontent-typeに関わらずhtmlとして認識されてしまうようです。
(画像のパスを隠すため、画像表示用のルーティングを作り、画像を直接表示していました)

$headers = array( 'Content-Type' => $typ, 'Content-Disposition' => 'attachment; filename="' . $fname . '"', 'X-XSS-Protection' => '1; mode=block', 'X-Content-Type-Options' => 'nosniff', ); return Response::make( readfile($src), 200, $headers );

結局、下記のように改修することで解決しました

header('Content-Type : '.$typ); header('Content-Disposition : '.'attachment; filename="' . $fname . '"'); header('X-XSS-Protection : '.'1; mode=block'); header('X-Content-Type-Options : '.'nosniff'); readfile($src);

ご回答いただき、ありがとうございました。

投稿2017/08/29 03:50

nasubi256

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問