経由にしたことである。拡張子をチェックし、次にユニークなファイル名を生成し、ファイルを作成してクローズし、削除せずにファイルのパスを返す。よりアップロードされたファイルで返されたパスのファイルを上書きする。作成したファイルを消してしまうとファイル名の一意性が保障されなくなる。注意:このダウンロードスクリプトにはクロスサイト・スクリプティング脆弱性があります。basename($file));?>このスクリプトはクエリー文字列fileでファイル名を指定する。拡張子をチェックし、その後それぞれの拡張子に対応したContent-Typeを出力し、ファイル本体をreadfile()で出力する。ファイル名をbasename()に通しているのはディレクトリ・トラバーサル脆弱性対策である。脆弱性発生の原因にアップロードファイル名にスクリプトを示す拡張を指定できることがあったが、それに対する確実な対策は容易ではない。どの拡張子がスクリプトを示すのかは自明ではないためである。よって、脆弱性の対策としては上記に示したアップロードファイルを公開ディレクトリに保存しない方法を用いる。Attack、サービス妨害攻撃)を仕掛けられる可能性がある。影響は応答速度の低下、最悪の場合はサーバの停止などがある。対策にはアップロードファイルの容量制限が有効である。設定することができる。アプリケーションの要求を満たす範囲でできるだけ小さな値にしておくことを推奨する。リクエストボディサイズを制限することもできる。PHP以外でも利用できることと早期のチェックでリクエストをエラーにすることでDoS攻撃耐性を高める上で有効である。下記はリクエストのボディサイズを100K日とに制限する場合の設定である。概要Webアプリケーションの開発に用いる言語の多くはシェル経由でOSコマンドを呼び出す機能を提供している。この機能の使い方に問題があると、意図しないOSコマンドが実行可能となる場合がある。これをOSコマンド・インジェクション脆弱性と呼ぶ。OSコマンド・インジェクション脆弱性は影響が大きく非常に危険な脆弱性である。以下は典型的な攻撃シナリオである。攻撃用ツールを外部からダウンロードする。ダウンロードしたツールに実行権限を与える。OSの脆弱性を内部から攻撃による権限昇格で管理者権限を得る。Exploit)Webサーバは攻撃者の自由になる。例として下記の問い合わせフォームを用いる。$mail");//以下略?><body>お問い合わせを受け付けました。メールのヘッダ(From、MIMEエンコードされたSubject、Content-Type)と本文である。正常系ではフォームのメールアドレス欄にメールアドレスを入力すれば、template.txtの内容のメールがそのメールアドレスに送られる。攻撃では例えばメールアドレス欄に以下を入力する。この例では表示するだけであるが、OSコマンド・インジェクション攻撃によりWebアプリケーションが稼動するユーザ権限で実行できるコマンドはすべて悪用が可能である。具体的にはファイルの削除、変更、外部からのファイルのダウンロード、ダウンロードしたツールの悪用などである。攻撃の例として、概要で述べたような手順によるサーバの管理者権限奪取があげられる。シェルには複数のコマンドを起動するための構文があるため、外部からパラメータを操作することにより元のコマンドに加えて別のコマンドを起動させられる場合がある。これがOSコマンド・インジェクションである。開発者がOSコマンドを呼び出す意図がなくても、無意識にシェル起動のできる関数を使っている場合もある。OSコマンド・インジェクション脆弱性が発生するケースは以下の2通りある。シェル経由でOSコマンドを呼び出す際に、シェルのメタ文字がエスケープされていない。シェル機能を呼び出せる関数を使用している。Unix系のシェルにおいて1行で複数のプログラムを起動する場合は以下の記法が使用できる。bbbaaabbb$この複数のプログラムを起動できるシェルの機能の悪用がOSコマンド・インジェクション攻撃である。OSコマンドのパラメータとして指定する文字列にシェルのメタ文字を混入させることで、開発者の意図とは異なるOSコマンドが実行可能となることOSコマンド・インジェクション脆弱性の原因である。OSコマンド・インジェクション脆弱性が生まれる条件は、以下の3つのすべてを満たすことである。シェルを呼び出す機能のある関数を利用している。シェル呼び出しの機能のある関数にパラメータを渡している。パラメータ内に含まれるシェルのメタ文字をエスケープしていない。対策は、採用すべき順に以下がある。OSコマンド呼び出しを使わない実装方法を選択する。シェル呼び出し機能のある関数の利用を避ける。外部から入力された文字列をコマンドラインのパラメータに渡さない。OSコマンドに渡すパラメータを安全な関数によりエスケープする。どの対策を選択するかは設計段階で決めておくべきである。設計の各フェーズでは以下の検討を推奨する。実装方式設計として以下を検討する。・主要な機能の実装方針を決定する。・その際に極力ライブラリを利用するが、やむを得ない場合はOSコマンドを利用する。以下、具体的な実装方法について説明する。●OSコマンド呼び出しを使わない実装方法を選択するOSコマンドを呼び出さない(シェルを呼び出せる機能を利用しない)ことにより、OSコマンド・インジェクション脆弱性が混入する可能性がなくなり、またOSコマンド呼び出しのオーバーヘッドがないことから多くの場合に性能も向上する。先の問い合わせに対してメールを送信する受付スクリプトをライブラリを使用して書き換えた例を示す。"お問い合わせを受け付けました。webmaster@example.jp");?><body>お問い合わせを受け付けました</body>ただし、メール送信機能についてはメールヘッダ・インジェクション脆弱性が混入する可能性がある(メールヘッダ・インジェクション脆弱性)。いうオプションを指定すると、宛先のメールアドレスをコマンドラインで指定する代わりに、メール内容のTo、CC、Bccの各ヘッダから読み取る。この機能を使うと、外部から入力された文字列をコマンドラインに指定せずに済むのでOSコマンド・インジェクション脆弱性の混入する可能性がなくなる。サンプルコードは以下。{die('ただいま混みあっています。8bitお問い合わせを受け付けました。EndOfMail;);pclose($h);?><body>お問い合わせを受け付けました。</body>ただし、メール送信機能についてはメールヘッダ・インジェクション脆弱性が混入する可能性がある(メールヘッダ・インジェクション脆弱性)。●OSコマンドに渡すパラメータを安全な関数によりエスケープする今までのパターンでOSコマンド・インジェクション脆弱性を解消できない場合にはシェル経由でOSコマンドを呼ぶことになる。OSコマンドに渡すパラメータをエスケープする必要があるがシェルのエスケープルールは複雑なので、安全なエスケープが行えるライブラリ関数を用いるべきである。sendmailコマンドを呼ぶ場合は以下のようになる。あるが、使い方によっては脆弱性の原因となるので推奨しない。使っても脆弱性が混入する可能性はありえる。よって、保険的対策としてパラメータの検証を行うことを推奨する。対策に漏れがあった場合のために、いかの保険的対策を推奨する。パラメータを検証する。アプリケーションの稼動する権限を最小限にする。Exploit)を受ける場合である。このためにパッチ適用を推奨する。外部から閲覧されると困るファイルをWebサーバの公開ディレクトリに配置していると、ファイルのURLがわかれば外部から閲覧が可能となる。これによって重要情報の漏洩が発生する。原因は非公開のファイルを公開ディレクトリに置くことである。公開ディレクトリに置いたファイルが外部から閲覧できる条件は以下である。ファイルが公開ディレクトリに置かれている。ファイルに対するURLを知る手段がある。ファイルに対するアクセス制限が掛かっていない。ファイルに対するURLを知る手段にはいかがある。ディレクトリ・リスティングが有効である。ファイル名が日付やユーザ名、連番など類推可能である。user.dat、data.txtなどありがちな名前である。エラーメッセージや他の脆弱性によりファイル名がわかる。外部サイトからリンクされるなどして検索エンジンに登録される。URLでディレクトリ名を指定した場合にファイル一覧を表示する機能をファイル・リスティングと呼ぶ。ファイルへのアクセス制限のみで対処するのは危険である。うっかりミスやサーバ移転の際の設定変更などアクセス制限が外れてしまう懸念がある。非公開ファイルを効果ディレクトリに置かないことである。そのためには以下が推奨される。アプリケーションの設計時にファイルの安全な格納場所を決める。レンタルサーバを契約する場合に非公開ディレクトリが利用できることを確認する。保険的にディレクト・リスティングを無効にする。以下のように設定する。以下のように設定する。記述してファイルの外部からの閲覧を禁止する設定をして暫定的に対処することができる。発生箇所ファイル名を外部から指定できるページ影響を受けるページすべてのページが脆弱性の影響を受ける。外部からパラメータでサーバ上のファイル名を指定できるWebアプリケーションでは、ファイル名に対するチェックが不十分であるとアプリケーションの意図しないファイルに対して閲覧や改ざん、削除ができる場合がある。これをディレクトリ・トラバーサル脆弱性と呼ぶ。画面のテンプレートファイルを指定できるスクリプトである。?>以下略</body>このスクリプトの正常系の実行例を示す。http://example.jp/sample.php?template=spring上記のURLでは/var/www/tmpl/spring.htmlが表示される。http://example.jp/sample.php?template=../../../etx/hosts%00この場合、ファイルパスは次のように組み立てられる。/var/www/tmpl/../../../etc/hosts[NULL].html"[NULL]"はヌルバイトを表す。ヌルバイトによりファイル名が終端され、正規化後のパスは/etc/hostsとなり、hostsファイルが表示される。このように、ディレクトリトラバーサル・トラバーサル脆弱性があるとWebサーバ上の任意のファイルにアクセスが可能となる。アプリケーションの実装によっては書き込みや削除が可能となる場合もある。ディレクトリ・トラバーサルを用いてPHPなどのスクリプトファイルに書き込みができると、Webサーバ上で実行することにより任意のスクリプトを実行できる場合があります。この際の影響はOSコマンド・インジェクションと同じで、外部から不正プログラムをダウンロードされたりシステムに対する不正操作が可能となる。脆弱性の原因ファイル名を外部から指定することができる。ファイル名として絶対パスや相対パスの形で異なるディレクトリを指定できる。組み立てたファイル名に対するアクセスの可否をチェックしていない。上記3つをすべて満たす場合にディレクトリ・トラバーサル脆弱性が発生する。上記、であげた原因のうちいずれか1つでも対応すれば脆弱性は解消する。以下、対策を説明する。●外部からファイル名を指定できる仕様を避けるファイル名を外部から指定できなくすれば、ディレクトリ・トラバーサル脆弱性を根本的に解決できる。以下の方法で可能である。・ファイル名を固定にする。・ファイル名を直接指定するのではなく番号などで間接的に指定する。●ファイル名にディレクトリが含まれないようにするファイル名にディレクトリ名が含まれないようにすれば、アプリケーションの想定したディレクトリのみにアクセスすることになりディレクトリ・トラバーサル脆弱性が解消する。ディレクトリを示す文字記号はOSにより異なるので、OSによる違いを吸収できるライブラリを使用するべきである。PHPの場合はbasename()が使用できる。basename()を用いた対策例を以下に示す。使用しても拡張子を変更される場合があるので注意が必要である。いうファイル名ができる。●ファイル名を英数字に限定するファイル名の文字種の仕様を英数字に限定すればディレクトリ・トラバーサル脆弱性への攻撃に用いる記号文字が使えなくなる。テクノポップのカリスマ。