Apache httpd + PHPな環境で閲覧できるファイルを調べるpmrというコマンドを開発した

このブログの対象読者

Apache httpd + PHPな環境で、本番運用をしているプログラマ、インフラエンジニア。

このブログが解決すること

Apache httpd + PHPな環境ではファイルの配置や、サーバの設定によっては、想定外のファイルにアクセスされることがあります。それは例えばpassword.conf のようなファイルが閲覧されたり、任意のphpファイルが意図しない実行をされたりすることにつながります。このブログでは、そういったアクセスが可能であるかどうかをチェックする手段を提供します。

pmr

pmrとは筆者が開発した、コマンドで、 Pyama Multi Request の略です。アーキテクチャとしては、標準入力から受けたファイルリスト + URLで並列的にアクセスを行い、レスポンスボディの10行とファイルの10行を比較し、一致している場合に、そのファイルが見えていると判定します。

例を示します。

$ wget https://pepabo.com
...
2018-02-24 10:35:47 (59.7 MB/s) - ‘index.html’ saved [33941]
$ echo index.html | pmr -url https://pepabo.com
INFO[0000] request: https://pepabo.com 200 OK
INFO[0000] request: https://pepabo.com/index.html 200 OK
WARN[0000] This file is published index.html

↑の実行例では、 https://pepabo.com にアクセスし、index.html を保存後、pmr に対して、標準入力から index.htmlを渡して実行しています。 pmrhttps://pepabo.com/index.html のように連結したURLでhttpアクセスを行い、レスポンスボディを比較した結果、内容が一致しているので、 WARN[0000] This file is published index.html のようにwarning表示を行っています。

また、応答が HTTP StatusOK(200) ではない場合もwarning表示が行われるので、意図しないphpにアクセスされて、 HTTP IntrenalServerError(500)などの場合も検知することが可能です。

pmrの具体的な使い方

pmrを実行するのは、WEBサービスのリポジトリのDocumentRootに相当するディレクトリで下記のように実行することを想定しています。

$ pwd
/path/to/service/public
$ find ./ -type f |grep -v -e '\.gif|\.png|\.jpg|\.js|\.css|\.html|\.ico|\.svg|\.pdf' | \
pmr -u https://example.com  2>&1 | grep WARN
# passwordっぽいのが見えっちゃってる
WARN[0000] This file is published password.html

このように pmr では標準出力からファイルリストをもらうことで、柔軟なアクセスを実現しています。例えば、本番サーバのDocumentRootからファイルリストを持ってくることで、ログファイルなどの本番サーバにしか無いファイルも調査することが可能になるでしょう。

pmr

最後に

昨今のWEBシステムにおいては、WEBアプリケーションフレームワークに則って開発すると、意図しないファイルの公開は限りなく少なくなると思いますが、黎明期の手違いや、複数人で開発している状況だと、意図しないファイルの公開が行われているかもしれません。そういったことを自動でチェックする仕組みとして pmr を是非活用いただければ嬉しいです。