###### tags: `安全なWebアプリケーションの作り方` # 4.10ファイルアクセスにまつわる問題 安全なウェブアプリケーションの作り方の勉強会資料です。 今回の勉強会では、以下2点を扱います。 * Webサーバ内のファイルに対する不正アクセス(ディレクトリトラバーサル) * OSコマンドの呼び出し(OSコマンドインジェクション)-> 4.11 ## 4.10.1 ディレクトリトラバーサル ### 概要 外部からパラメータ形式で、サーバ上のファイル名を指定できるWebアプリケーションに対する脆弱性。アプリケーションの意図しないファイルに対して閲覧・改ざん・削除できる。 ![](https://i.imgur.com/RqsV3GD.png) ### 攻撃手法と影響 <summary>/4a/4a-001.php</summary> ```php= <?php define('TMPLDIR', '/var/www/html/4a/tmpl/'); $tmpl = filter_input(INPUT_GET, 'template'); ?> <body> <?php readfile(TMPLDIR . $tmpl . '.html'); ?> メニュー(以下略) </body> ``` * 正常系実行 http://example.jp/4a/4a-001.php?template=spring * 攻撃系実行 http://example.jp/4a/4a-001.php?template=../../../../../etc/hosts%00 上記コードは、`/var/www/html/4a/tmpl/`以下の指定したファイルを 読み込む処理があります。 パラメータ`$tmpl=../../../../../etc/hosts%00`を指定することで、 意図しない階層にある`~/etc/hosts`のファイルが閲覧できます。 また、終端を意味するnullバイトを組み合わせることで、 拡張子`.html`以外のファイルを指定できます。 その他例:パスワードを表示させる http://example.jp/4a/4a-001.php?template=../../../../../etc/passwd%00 [/etc/passwdの構造について](http://www.wakhok.ac.jp/biblion/1997/sysadmin/node18.html) ### 脆弱性が生まれる原因 下記3つの条件すべてを満たしている場合、攻撃される恐れがあります。 * ファイル名を外部から指定できる * ファイル名として、絶対パスや相対パスの形で異なるディレクトリを指定できる * 組み立てたファイル名に対するアクセスの可否をチェックしていない ファイル名が芋づる式に漏洩する原理はコラム参照 ### 対策 #### 外部からファイル名を指定できる仕様を避ける --- * ファイル名を固定にする * ファイル名をセッション変数に保持する * ファイル名を直接指定するのではなく、番号などで間接的に指定する #### ファイル名にディレクトリが含まれないようにする --- ファイル名にディレクトリ名([.][/][:])が含まれないようにすれば、アプリケーションの想定したディレクトリのみにアクセス可能となります。 そこで、PHPの場合`basename`関数により、ディレクトリ含むファイル名の 最後の部分を返すことで対策できます。 ただし、nullバイト攻撃に対応できないため、拡張子が変更される恐れがあります。(php5.3.4以降ではエラーとなるように修正) [確認ページ](http://example.jp/4a/4a-001b.php?template=../../../../../etc/hosts%00) <summary>/4a/4a-001b.php</summary> ```diff= <?php define('TMPLDIR', '/var/www/html/4a/tmpl/'); - $tmpl = filter_input(INPUT_GET, 'template'); + $tmpl = basename(filter_input(INPUT_GET, 'template')); ?> <body> <?php readfile(TMPLDIR . $tmpl . '.html'); ?> メニュー(以下略) </body> ``` #### ファイル名を英語に限定する --- 正規表現による入力チェックを行うことが、対策として考えられます。 [確認ページ](http://example.jp/4a/4a-001c.php?template=../../../../../etc/hosts%00) <summary>/4a/4a-001c.php</summary> ```diff= <?php define('TMPLDIR', '/var/www/html/4a/tmpl/'); $tmpl = filter_input(INPUT_GET, 'template'); + if (preg_match('/\A[a-z0-9]+\z/ui', $tmpl) !== 1) { + die('templateは英数字のみ指定できます'); + } ?> <body> <?php readfile(TMPLDIR . $tmpl . '.html'); ?> メニュー(以下略) </body> ``` ### ディレクトリトラバーサルまとめ | 項目 | 内容 | | -------- | -------- | | 発生箇所 | ファイル名を指定できるページ | | 影響を受けるページ | 全ページが影響を受ける | | 影響の種類 | 情報漏えい、データ改ざん、削除、任意スクリプト実行、アプリケーションの機能の停止 | | 影響度合い | 大 | | 利用者の関与度合い | 不要 | | 対策 | [いずれかを実施](https://hackmd.io/d6kI6DZTTRiagZ7fnE854g?view#%E5%AF%BE%E7%AD%96) | ## 4.10.2 意図しないファイル公開 ### 概要 外部から閲覧されると困るファイルをWebサーバの公開ディレクトリに配置している場合があります。 この場合、ファイルに対するURLが分かると、情報の漏洩がおこります。 ### 攻撃手法と影響 URLでディレクトリ名を指定した場合に表示される機能を悪用しています。 http://example.jp/4a/data/ この機能をディレクトリ・リスティング(Directory Listing)と呼びます。 ファイル名をクリックすることで、内容を閲覧することができます。 ### 脆弱性が生まれる原因 #### 発生条件 --- * ファイルが公開ディレクトリに置かれている * ファイルに対するURLを知る手段がある * ファイルに対するアクセス制限が掛かっていない #### URLを知る手段 --- * ディレクトリ・リスティングが有効 * ファイル名が日付やユーザ名、連番など類推可能 * user.dat、data.txtなどのありがちな名前 * エラーメッセージや、他の脆弱性によりファイルのパス名が分かる * 外部サイトからリンクされるなどして検索エンジンに登録される ### 対策 * アプリケーション設計時に、ファイルの安全な格納場所を決める * レンタルサーバを契約する場合は、非公開ディレクトリが利用できることを確認する Apache HTTP Server の場合は`httpd.conf`を以下のように設定 ```env= <Directory パス指定> Oprions -Indexes その他オプション その他設定 </Directory> ``` 以上!