mod_securityは、GNUライセンスの下で公開されている、オープンソースのWAFである。mod_securityの公式サイトでは、「intrusion detection and prevention engine」と説明されている。
本稿ではmod_securityを動かす環境として、
RedHat Linux 9.0
apache 1.3.31(DSO対応版でソースからコンパイルしてインストール)
を使用した。ほかの環境でも導入手順は大して変わらないだろう。なお、Windows上のApacheでは試していないのだが、Windows版のmod_securityはソースではなくDLLで提供されているので、インストールに関しては特に難しいことはないと思う。
mod_securityは、以下のURLから最新版をダウンロードできる。
本稿執筆時点での最新版は1.8.2である。筆者は「mod_security-1.8.2.tar.gz」を使用した。コンパイル/インストールは以下の4ステップで終了する。
(1) tar zxvf mod_security-1.8.2.tar.gz
(2) cd mod_security-1.8.2
(3) cd apache1
(4) sudo /usr/local/apache-1.3.31/bin/apxs -cia mod_security.c
apache 2.xを使用している場合は、ステップ(3)で、ディレクトリ「apache2」に移動する。それ以外の手順は同じである。以上でモジュールが作成され、モジュールを読み込む設定がhttpd.confに書き込まれているはずである。
以降では、mod_securityの設定を行っていくことにしよう。mod_securityの設定は、ほかのモジュールと同じく、httpd.confを編集する。
mod_securityは、apacheに組み込むモジュールであるため、apacheが使用するデータすべてに対して処理を行うことができる。mod_security
が行う主なチェックを以下に示す。
また、それぞれのチェックに引っ掛かった場合の動作として、
などを指定することができる。
まずは以下の設定を見てほしい。
1: <IfModule mod_security.c> 2: 3: SecFilterEngine On 4: SecFilterScanPOST On 5: 6: SecFilterDefaultAction "deny,log,status:406" 7: 8: SecAuditEngine RelevantOnly 9: SecAuditLog logs/audit_log 10: 11: SecFilterSelective ARGS ("|>|<|'|script|onerror) 12: 13: </IfModule>
これは、非常に簡単なクロスサイトスクリプティング対策用の設定である。順に説明していこう。
3行目 | mod_securityの機能をONにする。ONにしないと全く動かない。 |
---|---|
4行目 | POSTデータもスキャンするようにする。 |
6行目 | フィルタにマッチした場合のデフォルト動作。 ここでは、 ・不許可 ・ロギング(apacheのエラーログに出力) ・ステータスは406(Not Acceptable)を返す という設定。 |
8行目 | フィルタにマッチした場合のみAuditログに記録。 このAuditログはデフォルト動作でのロギング用ファイルとは別物。 |
9行目 | mod_securityのAuditログファイル。 ここに出力される内容は8行目で指定したもの。 |
11行目 | URLパラメータとPOSTデータのすべてをチェック対象とする。 データ中に、正規表現「("|>|<|'|script|onerror)」にマッチする個所があるかどうかチェックする。 |
まずは上記のような簡単な設定を用いて、正しく動作するかどうか確認するところから入ろう。上記の設定をhttpd.confに書き込んだら、apacheを再起動しよう。このとき、ログファイル「audit_log」が生成されているか確認しておく。このファイルが生成されていない場合はインストールがうまくいっていない可能性があるので、インストール手順をもう一度見直してほしい。
mod_securityをインストールしたapache上に適当なCGIを作成しておこう。本稿では以前より使用しているショッピングサイトを使用することにする。
ログインフォームに「"><s>a</s>」と入力してみる(図3)と、エラー画面が表示される(図4)。このときステータスコードは406と表示されている。
また、同時にAuditログファイルにも出力されているので確認しておこう。攻撃リクエストがそのままの状態でログに出力されていることが分かる。
POST /login.cgi HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Accept-Language: ja Cache-Control: no-cache Connection: Keep-Alive Content-Length: 47 Content-Type: application/x-www-form-urlencoded Cookie: ss=300711200428072255 Host: www.example.com Referer: http://www.example.com/index.cgi User-Agent: Mozilla/4.0 mod_security-message: Access denied with code 406. Pattern match "(""|>|<|'|script|onerror)" at ARGS mod_security-action: 406 47 loginid=%22%3E%3Cs%3Ea%3C%2Fs%3E&password=aaaaa HTTP/1.1 406 Not Acceptable Keep-Alive: timeout=15, max=100 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: text/html; charset=iso-8859-1
今回は、非常に簡単なサンプル設定を用いて、mod_securityの動作説明を行った。mod_securityは、手軽にインストールでき、正しく設定すれば、かなり強固な防御策となり得る。前述したように、残念ながらmod_securityではロジック系の攻撃には対処することはできないが、オープンソースであるので、今後そのような機能が実装されていくことを期待しよう。次回はもう少し実践的なmod_securityの使用方法について説明することにする。
「第12回」へ→
中村隆之(なかむらたかゆき)
三井物産セキュアディレクション勤務。 セキュリティコンサルタントとして主にWebアプリケーションのセキュリティ検査に従事しており、大手ポータルサイト、オンラインバンキングなどの数多くの 検査実績を持つ。また、セキュアネットワーク及び暗号関連の研究に携わり、大手製造、官公庁、金融機関へのセキュリティシステム導入など数多くの実績を持つ。
主に、不正アクセス監視サービス、セキュリティ検査、セキュリティポリシー策定支援などのサービス提供している。また、セキュリティに関する教育サービスも実施中。
Copyright © ITmedia, Inc. All Rights Reserved.