」のサンプルスクリプトにリモートスクリプト実行の脆弱性があるので報告します。はじめにYahoo!知恵袋の質問を読んでいたら、以下の質問がありました。(発行)リックテレコムP112の画像をアップロードする機能でエラーがでます。質問に対しては回答が既についてクローズされていましたが、引用されているソースを見て任意のファイルを任意のファイル名で、Web公開ディレクトリにアップロードできることに気づきました(下記)。print'画像が大き過ぎます。}}ご覧のように、ファイルサイズの確認はしているものの、ファイルの中身とファイル名については制限がありません。この結果、以下の脆弱性が生じます(代表的なもののみ)。PHPスクリプトをアップロードされ、攻撃者がリモートから任意のスクリプトをWebサーバー上で実行できるHTMLファイルをアップロードされ、利用者のブラウザ上で任意のJavaScriptを当該ドメイン上で実行されられる(XSSと同等の影響)本稿では、前者のリモートスクリプト実行について説明します。同書P112の段階ではログイン機能が実装されていませんが、最終的にはこのアップロード機能は店舗スタッフとしてログインした利用者のみが実行できます。スタッフだからリモートスクリプト実行できても大丈夫、とは言えません。店舗スタッフには商品情報のメンテナンスの権限はありますが、任意のスクリプト実行の権限まではないと考えられるからです。このため、店舗スタッフがリモートスクリプト実行ができてしまう時点で脆弱性と言えます。現実の運用では、店舗スタッフにサーバーメンテナンスの権限もある(rootパスワードを正当に知っているなど)状況も考えられます。この場合、この脆弱性による実害はなく、運用上許容し得る場合もあるでしょう。CSRF攻撃によるファイルアップロードの可能性それでは、店舗スタッフ以外の人が、任意ファイルをアップロードできる可能性はないでしょうか。これができると重大な脆弱性となります。実は、店舗スタッフに対してCSRF攻撃をかけると、第三者が任意ファイルをアップロードできてしまいます。以下、その方法を説明します。CSRF攻撃の場合、店舗スタッフとしてログイン中のブラウザから以下のリクエストを送信できることが必要です。※任意のPHPコード----BNDRY--通常のHTMLフォームを使ったCSRF攻撃では、Content-Typeをmultipart/form-dataにすることまでは可能ですが、ファイルの中身とファイル名を指定する方法がありません。従って、HTMLフォームによる攻撃経路はありません。Level2)を使うと、POSTするデータの中身を任意に指定することができ、CSRFによるファイルアップロードが可能になります。Sharing)による保護があるので、対象サイト側で明示的に許可しないとリクエストが送れないはずではないかという疑問が生じるかもしれません。CORSによるクロスオリジン通信の制御は、XMLHttpRequestによって送信したリクエストに対して、HTTPレスポンスを送信元のスクリプトが受け取れるか否かに関係します。HTTPリクエストを送信するだけであれば、相手側の許可がなくてもできてしまいます。CSRF攻撃は、HTTPリクエストが送信できれば攻撃可能であり、HTTPレスポンスは必要ありません。Level2対応のブラウザを使っていれば、以下のようなワナサイトを閲覧した場合、スタッフが知らないうちに、ファイルアップロードのリクエストを自分のブラウザから送信してしまうことになります。あるのは、XMLHttpRequestのリクエストにクッキーを付与せよという指令です。これがないと、スタッフのログイン状態でのリクエストにならず、CSRF攻撃は成立しません。上記JavaScriptを適当な罠に仕込んでおき、店舗スタッフがうっかり閲覧してしまうと、以下のリクエストが店舗スタッフのブラウザから送信されます。phpinfo();----BNDRY--このリクエストを見ると、以下のことがわかります。クロスドメインで確かに攻撃リクエストが送信されている。multipart/form-dataの形式のデータが送信されており、PHPスクリプトがアップロードされる認証Cookieが送信されていて、認証状態でリクエストが受け付けられるOriginヘッダとRefererヘッダがワナサイトを示しているが、元のPHPスクリプトはこれらをチェックしていないので攻撃には影響ないこのスクリプトをCSRF攻撃でアップロードされたタイミングを見計らって、攻撃者が/gazou/a.phpにアクセスすると、以下のようにphpinfoが表示されます。いうことで、第三者が勝手なPHPスクリプトをアップロードして実行できることを確認しました。対策サーバーサイドのスクリプト実行を防ぐための最低限の対策は以下となります。アップロードするファイル名の拡張子を画像のもの(.jpg等)に制限するですが、元のスクリプトは色々心許ない感じです。ファイル名の衝突があった場合、元々あった画像に上書きされてしまいますが、それをチェックする仕組みはなく、運用でカバーするしかありません。このあたり、本当に「プロ並み」となるには、配慮しなければならないポイントが多くありそうです。サーバーサイドのスクリプト実行脆弱性がきわめて危険であることを考えると、保険的な対策として、以下を推奨します。アップロードされた画像は公開領域に保存せず、スクリプト経由でダウンロードさせるようにする本稿では説明していませんが、アップロードした画像ファイルを悪用したクロスサイト・スクリプティング(XSS)攻撃もあり得ます。詳しくは下記をご覧下さい。対策としては下記を推奨します。レスポンスヘッダとして送信する具体的なプログラミング例については、下記参考書をご確認ください。脆弱性が生まれる原理と対策の実践さらに、CSRF脆弱性については、ふつーに対策してください。まとめ書籍「気づけばプロ並みPHP」のサンプルスクリプトにリモートスクリプト実行の脆弱性について報告しました。ファイルアップロード単体では、ログインユーザのみが悪用できる脆弱性ですが、CSRF脆弱性を組み合わせることにより、第三者が任意のPHPスクリプトをアップロードできることを示しました。