ModSecurity for Apache User Guide

Manual Version 1.9 / Revision 1 (November 6, 2005)

Copyright © 2002-2005 Thinking Stone  ( 
http://www.modsecurity.org  )

Table of Contents

Introduction
Licensing
Acknowledgements
Contact
Installation
CVS Access
Nightly Snapshot Download
Stable Release Download
Installing from source
Installing from binary
Configuration
Turning filtering on and off
POST scanning
Turning buffering off dynamically
Controlling ModSecurity dynamically
Chunked transfer encoding
Default action list
Implicit validation
Filter inheritance
Filter inheritance In multiuser environments
URL Encoding Validation
Unicode Encoding Validation
Byte range check
Allowing others to see ModSecurity
Rules
Simple filtering
Path normalisation
Null byte attack prevention
Regular expressions
Inverted expressions
Advanced filtering
Argument filtering exceptions
Cookies
Output filtering
Actions
Specifying actions
Per-rule actions
Restricting what can appear in the per-rule action list
Built-in actions
Request headers added by mod_security
Logging the request body
Handling rule matches using ErrorDocument
Making ModSecurity talk to your firewall
Special Features
File upload support
Server identity masking
Chroot support
Logging
Debug Log
Audit logging
Guardian log
Custom logging
Miscellaneous Topics
Impedance mismatch
Testing
Solving Common Security Problems
PHP
Performance
Important notes
Changing the Apache hook at which mod_security runs
Examples
Parameter checking
File upload
Securing FormMail
Appendix A: Recommended Configuration

Introduction

ModSecurityは、オープンソースの侵入検出およびウェブアプリケーション用の防御エンジンです。同様にアプリケーションファイヤーウォール と呼ぶ事ができます。それはウェブサーバへ埋め込まれて動作します。強 力な傘のように振舞い-アプリケーションを攻撃から遮断します。ModSecurityはWEBサーバーへのWEB攻撃の処理能力を増加し統合します。

言及する価値がある特徴は次のとおりです:
ModSecurityは、攻撃を検知するか、あるいは攻撃を検知し防御する為に使用することができます。

Licensing

Mod_securityは2つのライセンス下で利用可能です。ユーザーは、GNU一般公開ライセンス条件の基でソフトウェアの使用を選択することが できます。
(http ://www.gnu.org/licenses/gpl.html ) Open Source / Free Software 製品としてです。代替の、クローズドソースの製品の配布に商用ライセンスが利用可能です:
セキュリティ機器,WEBサーバー用の、個々又はサイト全体に展開するエンドユーザーライセンス、アプリケーション配布用クローズドソースOEMライセン スです。商用ライセンスの詳細情報については、 Thinking Stone Ltd に連絡をとってください。

Thinking Stone Ltd

Tel: +44 20 8141 2161
Fax: +44 87 0762 3934
http://www.thinkingstone.com
<contactthinkingstone.com>

Acknowledgements

このモジュールは、Apache ウェブサーバーを作成した素晴らしい人々抜きでは可能では無かったでしょう、私はかつて素晴らしい人々からApacheモジュール・プログラミングを学習 し、 Apacheモジュールを構築して多くの時間を過ごしました。私は mod_rewrite を設計し書き上げた皆さんに特別な感謝を致します。

Contact

ModSecurity は Ivan Ristic と Thinking Stone によって開発されています。コメントと追加機能のリクエストを歓迎します。<ivanwebkreator.com>に電子メールを送ってく ださい。

注記
どう か、私の個人用メールアドレスにサポートの要求を送らないで下さい。私は質問に答えるのに時間を費しています。しかし、もはや私的な質問には答えませ ん。回答する事で、別のユーザーが自身でメールアーカイブを探す事を抑制する結果になるからです。あなたが回答を直ちに必要とする、又は、あなたが望むな らば回答時間を重視し保証するThining stone 商用サポートにしてください。


Installation

インストールを始める前に、好ましいインストール方法を選ぶ必要があるでしょう。最初に、最新の ModSecurityバージョン(恐らく不安定だが、最高の機能)を直接インストールするべきかCVSから最新の安定したリリース (推奨)を使用するべきか決める必要があります。あなたが stable リリース(安定版)を選べば、バイナリから ModSecurityをインストールするか、ソースコードからコンパイルすることが可能です。次の数ページは、関連する内の別の1つの方法を選ぶ利点に ついてより多くの情報を与えます。

CVS Access

モジュールの最新のバージョンにアクセスしたければ、CVSによって得る事ができます。変更リスト、最後に作られた安定版リリースは通常ウェブサイト で入手可能です。(ファイル CHANGES 中)ModSecurityの CVS は SourceForge によってホストされています。(http://www.sf.net) 直接アクセスするか、あるいはウェブからこのアドレスを使用して見ることができます:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mod-security/

あなたのコンピュータにソースコードをダウンロードするには次の2つのコマンドを実行します:

cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/mod-security login
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/mod-security co mod_security
1行目は、匿名ユーザーとしてあなたはログインし、2行目でリポジトリにおいて利用可能なファイルをすべてダウンロードするで しょう。

Nightly snapshot download

CVSが好きでは無いが、最新のバージョンを望むなら、次のアドレスから最新のナイトリー版の tarballをダウンロードすることができます:
http://www.modsecurity.org/download/snapshot/mod_security-snapshot.tar.gz
mod_securityの新機能は、退行テストに合格したそれぞれの変化が一つずつ加えられます。これは、CVSから利用可能なバージョンが常に使用可 能であることを保証します。

Stable Release Download

安定版リリースをダウンロードすることができます。http://www.modsecurity.org/download/ に行きます。バイナリ配布は時には役に立ちます。もしそれが必要なら、それらはダウンロードページにリストされています。そうでなければソースコードをダ ウンロードしてください。

Installing from source

ソースからインストールする場合2つの選択肢があります:ウェブサーバー自体へモジュールをインストールする方法と動的な共有されるオブジェクト (DSO) で mod_security をコンパイルする方法です。

DSO

DSOとしてインストールのは簡単です。また、手順は両方のバージョンの Apacheとも同じです。最初にどこかに mod_security のソースコードを展開します。(どこでも良い)それからモジュールをコンパイルします。
/apachehome/bin/apxs -cia mod_security.c
その後に Apache を Stop し、Start する必要があります(もし Restart したなら Segfault します)
/apachehome/bin/apachectl stop
/apachehome/bin/apachectl start
注記
私は、apxsユーティリティをインストールしないプラットフォームを使用している人々からの報告を持っています。
あるUnixディストリビューションでは、このツールは個別のパッケージで配布されています。そのパッケージがインストールされていないデフォルトでは問 題 が生じます。この問題を解決するには、あなたがどのようにして自分のカスタムApacheモジュールを加えることができるのかベンダーのドキュメンテー ションを読んでください。(いくつかのRedHatプラットフォームにおい ては、apxs にアクセスするために http-devel パッケージをインストールする必要があります)

Static installation with Apache 1.x

モジュールが静的にコンパイルされる場合はウェブサーバー自体に埋め込まれます。この方式は結果的に、わずかに速く実行可能です。しかしそのコンパイル方 法(のちのメンテナンスも)は少し複雑です:
配布物を展開した後 mod_security.c を Apache のソースコードツリー中の /src/modules/extra にコピーします。新しいモジュールを有効にするコンフィグレーションスクリプトの再構成を行います。
$ cd <apache1-source>
$ cp <modsecurity-source>/apache1/mod_security.c ./src/modules/extra
$ ./configure \
--activate-module=src/modules/extra/mod_security \
--enable-module=security
コンパイル、インストール、そしてWEBサーバーを普通にスタートします。

Static installation with Apache 2.x

Apache 2.x で静的コンパイルするには、単にApache のソースコードツリーにモジュールソースコードをコピーし、Apache を再構成します。

$ cd <apache2-source>
$ cp <modsecurity-source>/apache2/mod_security.c ./modules/proxy
$ ./configure \
--enable-security \
--with-module=proxy:mod_security.c

Integrating into the Apache 2.x build

あなたはmodsecurity を組み込んだApache 2x ビルドを選択できます。

$ cd <modsecurity-source>/apache2
$ mkdir -r <apache2-source>/modules/security
$ cp mod_security.c Makefile.in config.m4 <apache2-source>/modules/security
$ cd <apache2-source>
$ ./buildconf

modsecurity上のこの場所に他のApacheビルトインモジュールと共に見えます。

$ ./configure --enable-security

Installing from binary

いくつかの状況では、バイナリとしてモジュールをインストールしたいと思うでしょう。そのときは、私は単に Windows バイナリをダウンロードし利用可能にしています。バイナリからインストールするとディストリビューション中に2つのDSOライブラリを持っているでしょ う,メジャーApacheブランチ用各一。使用して いるバージョン用の適切なファイルを選択します。次に下記で述べる手続きに移ります:

Apache 1.x

mod_security.so(Unix)あるいはmod_security.dll(windows)ファイルをlibexec/にコピーする。(こ のフォルダーはApache設置パスの相関的な場所にあります。ソースツリーでは有りません)httpd.confファイルに次の行を加えます。
LoadModule security_module  libexec/mod_security.so

あなたの現存するコンフィグレーションに依存します。(明示的なモジュールロード順を構成しているかもしれない)AddModuleディレクティブを使用 して、モジュールをアクティブにすることが必要かもしれません:

AddModule mod_security.c

ほとんどの場合、どこに行を加えるかは重要ではありません。mod_securityを実行させる為のモジュールチェーンの最後が(そして、事実上、内部 でchroot機能を使用するつもりならば義務的)推奨されます。詳細は "Required module ordering for chroot support (Apache 1.x)"セクションを読んでください。

Apache 2.x

mod_security.so (Unix)または mod_security.dll (Windows)をmodules/にコピーする。(こ のフォルダーはApache設置パスの相関的な場所にあります。ソースツリーでは有りません)httpd.confに次の行を加えます。
LoadModule security_module modules/mod_security.so

Configuration

Mod_securityの設定ディレクティブは、あなたのコンフィグレーションファイルに直接加えます。WEBサーバーのスタートで常にモジュールの有 効、無効が確実でないなら、お決まりの設定ディレクティブの中の<IfModule>コンテナタグで囲みます。これでモジュールが有効になっ ていない場合 Apache が設定ディレクティブを無視する事ができます。
 <IfModule mod_security.c>
 # mod_security configuration directives
 # ...
 </IfModule>
以前からApacheは設定データが1ファイル以上有る事を許容しているので、単一ファイル(例えばmodsecurity.conf)である httpd.conf の Include ディレクティブで ModSecurity 設定ディレクティブのグループを含ませる事ができます:
Include conf/modsecurity.conf

Turning filtering on and off

フィルタリングエンジンはデフォルトでは Off になっています。モニタリング開始要求は設定ファイルに下記を加えます:
SecFilterEngine On
このパラメーターに対してサポートされる値は次のとおりです:

POST scanning

リクエストボディペイロードスキャンニング(あるいはPOSTペイロード)のデフォルトは Offです。使用するには、次のように On にします:
SecFilterScanPOST On
ModSecurityは、リクエストボディの2つのエンコードディングタイプをサポートしています:
他のエンコーディングは、殆んどのWEBアプリケーションで使用されません。確実に2つのエンコードタイプだけをウェブサーバーが受け取るようにするに は、設定ファイルに次の行を加えてください:
SecFilterSelective HTTP_Content-Type \
"!(^$|^application/x-www-form-urlencoded$|^multipart/formdata;)"

Turning buffering off dynamically

リクエストベースでPOSTスキャニングしない事は可能です。環境変数 MODSEC_NOPOSTBUFFERING が定義された事をModSecurityが検出した場合、POSTペイロードバッファリングを行なわないでしょう。例えば、ファイルアップロードの POSTペイロードバッ ファリングを行わないようにするには、下記を行います:
SetEnvIfNoCase Content-Type \
"^multipart/form-data;" "MODSEC_NOPOSTBUFFERING=Do not buffer file uploads"
MODSEC_NOPOSTBUFFERING 変数に割当てられた値はデバッグログに書かれます。そこに、なぜバッファリングしないのかを伝える為に記入する事ができます。

Controlling ModSecurity dynamically

更に リクエスト単位で ModSecurity を有効、無効にする事ができます。これは、SetEnvIf と SetEnvIfNoCase ディレクティブを組み合わせて MODSEC_ENABLE 環境変数によって行っています。MODSEC_ENABLE がセットされてない場合、SecFilterEngine で指定された設定が使用されるでしょう。 MODSEC_ENABLE がセットされた場合、SecFilterEngineの値が無視されます。 MODSEC_ ENABLE の値は SecFilterEngine ディレクティブと同じで次の通りです: On, Off, 又は DynamicOnly

Chunked transfer encoding

ペイロードサイズが前もって知られていない場合、HTTPプロトコルは、リクエスト・トランスファーメソッドをサポートします。リクエストボディはチャン ク中で運ばれます。従って名前は chunked transfer encoding です。 ModSecurityはchunked requests を現在サポートしていません;リクエストが chunked encoding で作られたリクエストボディは無視します。私が知っている限り、ブラウザは、リクエストを送信するために chunked encoding を使用していません。けれども Apache はこのエンコードをサポートしますが多くのモジュール(例えば、PHP module)は動作しません。これまで放置されアタッカーに悪意のあるペイロードを忍び込ませる機会を与えていま す。この弱点をexploitする攻撃者を防ぐために設定ファイルに次の行を加えてください:
SecFilterSelective HTTP_Transfer-Encoding "!^$"
これは、chunked trancefer encording を使って応答を送る性能に影響しないでしょう。

Default action list

常にルールはリクエストに対してマッチし、一つかそれ以上 Action を行う。個々のフィルターは各々自分のアクションを行うことができます。 し かし、すべてのフィルターの為のアクションのデフォルトセットを定義するほうが簡単です。(望むなら常にルール毎のアクションを行う事ができます)あなた は SecFilterDefaultAction ディレク テブィブでデフォルトアクションを定義します。例えば、下記は各ルールにマッチしログするエンジン設定で、要求はステータスコード404で拒否します:
SecFilterDefaultAction "deny,log,status:404"
このディレクティブは単に1つのパラメーターで、カンマ区切りで分離したリストのアクションを受け付けます。ここで指定するアクションは単独でアクショ ン・リストを持っている規則を除いてすべてのフィルタ一致上で行なわれるでしょう。

注記
1.8.6時点で、あなたが指定した致命的で無いデフォルトアクションリスト(例えばlog, passのようなリクエストをrejectしないリスト)を 指定したら、そのようなアクションリストは初期設定過程で無視されます。初期設定過程は、リクエストに関する情報を集めることを目指しています。致命的で 無いアクションの許可は数個のリクエストを見つけられなくします。この情報が内部処理のために必要になるので、そのようなアクションは許可することができ ません。もし、あなたがModsecurityを"detect-only"モードのオペレーションが必要なら全ての暗黙の検証を無効にする必要がありま す(URL encoding validation, Unicode encoding validation, cookie format validation, and byte range restrictions)

注記
いくつかのアクションはデフォルトリストに現れません。次のとおりです: id, rev, skipnext, chain, chained.

Implicit validation

1.8.6時点の暗黙のリクエスト検証は(設定したならば)リクエスト処理の最初だけに行われるでしょう。暗黙の検証はリクエストとヘッダ行チェックを両 立します。

注記
1.9dev4 時点で、最初の暗黙のリクエスト検証の一部の Unicode エンコーディング検証はRefererヘッダーコンテンツには適用されません。これはこのヘッダが他のウェブサイトからの情報を時々含んでいるからです。 また、それらのエンコーディングは通常保護されたウェブサイト上で使用されるエンコーディングと異なります。

Filter inheritance

親フォルダーに定義されたフィルターは、通常、ネスト(入れ子の)した Apache の設定によって継承されます。この性質はほとんどの(要求した)場合、 受 理される。しかし全てではありません。時々、サイトのある部分のチェックを緩める必要があります。下記の SecFilterInheritance ディレクティブを使います:
SecFilterInheritance Off
取り消す事から始めて、親フィルターを無視するようにModSecurityに指示することができます。このディレクティブはルールだけに影響します。こ の設定は、親コンテキストから常に継承されます。しかし、適切な設定ディレクティブで上書きする事で、それを無視することができます。
注記
設定とルールの継承は、常にデフォルトで有効です。もしあなたがもう 一つ下に設定コンテキストを持っているなら継承されません再び明示的に継承を無効にする必要があります。
親コンテキストからの規則を継承しない場合、新しいコンテキストのための新しい規則を書くか、ある いは単に、様々なコンテキストへ同じ規則を含めるのに誘導用のIncludeディレクティブを使用することができます。時々、子コンテキスト中のルール セットの小さな変更のみ必要になります。そのような場合、inheritanceオプションを選択しても良い。次の2つのディレクティブの助けを借りてこ れを行えます:
SecFilterImportとSecFilterRemoveの両ディレクティブはルールIDリストを受理する。ターゲットルール は、それらとIDの関連付けは必須です。(これはidアクション使用済み)ディレクティブは、それらがオーダーされ設定ファイルに現われると実行されるで しょう。従って、SecFilterRemoveのルールを削除し、次に、SecFilterImportでそれを再び加えることは可能です。以下に同じ ルール設定に到達するが、そこに着くために異なるルートをとる2つの例を見つけることができます。
注記
目標のルールIDがチェーンの一部であるルールを参照するなら、インポートと削除ディレクティブは全体のチェーンに影響、IDが参照するルールだけでは無 い。
例1: 親コンテキストからのルールは継承されません。しかし、単一のルールがインポートされます。

SecFilter XXX id:1001
SecFilter YYY id:1002
SecFilter ZZZ id:1003

<Location /subcontext/>
   SecFilterInheritance Off
   SecFilterImport 1003
</Location>

例:2 親コンテキストのルールは削除された2つのルールに継承されます

SecFilter XXX id:1001
SecFilter YYY id:1002
SecFilter ZZZ id:1003

<Location /subcontext/>
   SecFilterRemove 1001 1002
</Location>

注記
Apacheウェブサーバーは様々なタイプのコンテキストをサポートします(例えば <Directory...>, <Locatio>, <files>, ...)コンテキストがマージされるオーダーは重要。継承および異なるタイプのコンテキストを混用しないようにすべき。コンフィグレーションテスト確認、 意図した動作確認、Apacheコンテキストマージドキュメントを注意深く読む: http://httpd.apache.org/docs-2.0/sections.html#mergin.

Filter inheritance In multiuser environments

マルチユーザー環境でModSecurityを配備し、ユーザーが、.htaccessファイル中でルールを使用する事を認める場合、それらが親コンテキ ストからのルールを継承しないことを認めたく無いでしょう。これを行う2つの方法があります。

注記
もしも、信頼し得ないユーザーならば(例えば、WEBホスティング環境での実行)彼らにModsecurityへのアクセスを決して認めてはいけませ ん。.htaccess機構はアプリケーションコードとModsecurityの設定維持の集中管理制御の分散化に役立ちます。しかし、設定を覆したい ユーザーに意図的に使われてしまいます。もし、あなたが相反する環境を実行しているなら、あなたは、.htaccess機能実装を切る- DDISABLE_HTACCESS_CONFIGスイッチでModsecurityをカスタムコンパイルすべきです。

一つ目は、あなたは一定のルールを強制するマーク、 mandatory (強制)アクションを使えます。そのようなルールは、子コンテキスト中で常に継承されるでしょう。

別の方法は、 SecfilterInheritanceMandatoryに対して、強制コンテキスト中に全ての子コンテキストをシンプルに全てのルー ルを作ります。 

SecFilterInheritanceMandatory On

注記
 SecFilterInheritance がコンテキスト中で常に enabled になり、SecFilterInheritanceMandatory は、常にコンテキスト中で disabled になります。親コンテキスト中で使っている値は問題ありません。
あなたはこの状況に何が起こったのか驚くかもしれません:

SecFilter XXX id:1001
SecFilterInheritanceMandatory On

<Location /subcontext/>
      SecFilterInheritance Off
      SecFilter YYY id:1002
      SecFilter ZZZ id:1003,mandatory
</Location>

<Location /subcontext/another/>
      SecFilterRemove 1001 1002 1003
      SecFilter QQQ id:1004
</Location>

主な情況においてルール継承が強制的であるので、 /subcontext/ コンテキストは、そうしない為に、試みにも係わらずルール1001を継承するでしょう。(SecFilterInheritance Off 使用)このサブコンテキストは最初にルール1001を実行し、1002と1003が続きます。メインコンテキストの強制ルール1001 は、更に展開するコンテキスト /subcontext/another/ の意地悪な削除の試みにも関わらずです。更にこれは1003でも真です。mandatoryアクションを使い強制的な継承を構成します。しかしながら、 SecFilterRemove 1001 1002 1003 ディレクティブは、強制的で無い/subcontext/ を継承しているので削除ルール1002は成功する。このコンテキストは、故に最初に1001と 1003を実行し、ルール1004が続く。
注記
あなたは、以前の skip アクションを作り使う事を避け、且つ、ルールを削除すべきです。そうでないならば、あなたの意図に相当する何某かの設定に、とても注意しなければいけませ ん。

URL Encoding validation

URL文字列中においてはそれらを送信する前に特別な文字にエンコードする必要があります。XYが16進法の文字コードである場合、どの文字も3文字のコ ン ビネーション%XYを使用して置き換えることができます(詳細は http://www.rfc-editor.org/rfc/rfc1738.txt を見てください)16進法の値は、単に文字にAからFを割当てます。しかし、攻撃者は、しばしばデコードするアルゴリズムを騙すために他の文字を使用しま す。mod_securityは与えられたエンコーディングすべてをチェックし、それらが有効であることを確認します。あなたが持っている設定コンテキス ト直下の

次の行でURLエンコーディングの検証を展開します:
SecFilterCheckURLEncoding On
注記
このディレクティブはPOSTペイロード中に"multipart/formdata"エン コーディング(file upload)を使っている場合、エンコーディングをチェックしません。それはURLエンコード使用に必須では無いので必然的にこのエンコーディングは使 われていません。

Unicode encoding validation

他の多くの機能同様に Unicode encoding 検証はデフォルトで無効になっています。もし、あなたのアプリケー ション及は基本オペレーティングシステムがユニコードを " 受理 / 理解 " するなら展開すべきです。
注記
UnicodeとUTF-8エンコーディングについてのより多くの情報はRFC 2279に見つけることができます。
(http://www.ietf.org/rfc/rfc2279.txt)
SecFilterCheckUnicodeEncoding On
この機能はUTF-8エンコーディングチェックの次の3つのタイプのエラーとみなすでしょう。


Byte range check

リクエストを固定のバイトを両立する一定のバイトレンジに強制できる。これはスタックオーバフロー攻撃に役立ちます。(それらが通常"ランダム"な2進数 の内容を含んでいるので)

単に32〜126(総括的に)バイトまでを許可するには、次のディレクティブを使用してください:
SecFilterForceByteRange 32 126
デフォルト範囲は0と255です、つまり、全てのバイト値が許可されます。
注記
このディレクティブは、multipart/form-data エンコーディング(ファイル・アップロード)が使用される 時、POSTペイロード中のバイトレンジをチェックしないでしょう。これを行う事でバイナリファイルのアップロードが防止できます。但し、それらのリクエ ストは有効な範囲にあるかチェック後にパラメータが抽出されます。

Allowing others to see ModSecurity

1.9以前に Modsecurity は SecServerResponseToken ディレクティブをサポートしました。使用されると、このディレクティブはウェブサーバシグネチャでモジュール(バージョンを)の存在を表示しました。この ディレクティブは、1.9では動きません。もし使用されれば、それはエラーログに警告メッセージを出すでしょう。

Rules

フィルタリングエンジンが有効なら処理前に入って来るすべてのリクエストは遮断され解析されます。分析の最初に、リクエストフォーマットを有効にする定め られた一連の組込み済み検査を行ないます。これらのチェックは、設定ディレクティブを使用してコントロールすることができます。第2の段階中で、リクエス トはリクエストと逆に対抗させる一連のユーザー定義フィルターを通ります。肯定的一致がある場合は常に、所定のアクション がとら れま す。

Simple filtering

mod_securityフィルタリングの一番単純な形式を示します。すごく、シンプルです。こんな風に見えます:
SecFilter KEYWORD
個々の単純なフィルターは、mod_securityがリクエスト中のキーワードを捜します。検索はかなり広範囲です;それは、リクエストの最初の行 に適用されます。("GET /index.php?parameter=value HTTP/1.0"のように見えるもの)POSTリクエストの場合には、リクエストボディも検索されるでしょう。(リクエストボディバッファリング有効を 規定しているならば)

Path normalization

フィルターは生のリクエストデータには適用されず、代わりに標準化されたコピー上で行います。私たちは、攻撃者が検出を回避するために様々な忌避テクニッ クを適用 する ことができ るので(そして行うので)これを行います。例えば、シェル・コマンド実行を検知するフィルターのセットアップを望むなら:
SecFilter /bin/sh
しかし、攻撃者は文字列 /bin/./sh を指令中に入れて使用しフィルターを回避します。

ModSecurityは自動的に下記の変換を適用します:
下記のチェックを可能にするか不能にするか選択する事ができます:

Null byte attack prevention

Nullバイト攻撃はC/C++ベースのソフトウェアに対してトライされ、間違い無くそのすぐ前で文字列終わりだと考えさせるトリックを挿入しアプリケー ション を混乱させます。この タ イプの攻撃は適切な SecFilterByteRange フィルターで典型的に拒否しています。但し、Nullバイトを使わなければ ModSecurity の処理を邪魔する事ができます。これと戦うた めに、ModSecurityはデコード過程中で Null バイトを捜し、それらをスペースに変換します。そう...このフィルターの前述のところで...:
SecFilter hidden
リクエスト中に含まれた言葉 "hidden" は検出しません。:
GET /one/two/three?p=visible%00hidden HTTP/1.0
予想通りに作動します。

Regular expressions

私が前に説明したフィルタリングの最も単純な方法より、少々複雑です。
その全ての構文は以下のとおりです:
SecFilter KEYWORD [ACTIONS]
まず最初に、キーワードは単純なテキストではありません。正規表現です。正規表現はテキスト中のパターンマッチング用に設計されたミニプログラミング言語 です。大部分をこの強 力なツールで(今)作る為に、正規表現をよく理解する事を必要とします。私は、次の資料のうちの1つからあなたが始めるように推奨します:
注記
2つの異なる正規表現エンジンが Apache 1.x と Apache 2.x で使われています。Apache 1.x は POSIX 準処の正規表現エンジンです。Apache 2.x は PCRE 準処の正規表現エンジンです。経験則では、Apache 1.xで働く正規表現は Apache 2.x で働く。しかし反対は働かない。もし、両方のメジャーブランチで働くルールを書く必要があるなら、それらを徹底的にテストしなければならないでしょう。
2番目のパラメータはアクションリストの定義です。それは、フィル ターに一致する場合、何が起こるかを示します。アクションは、このマニュアル中で後述し説明されます。

Inverted expressions

感嘆符(!)が正規表現の最初の文字である場合、フィルターは、その正規表現を逆に扱うでしょう。
SecFilter "!php"
phpというワードを含んでいないリクエストをすべて拒否するでしょう。

Advanced filtering

SecFilterは、あなたが早々にスタートを切る事を可能にしていますが、検索の実行がとても広範囲で全然有効に働かない事に,すぐに気付くでしょ う。 別のディレクティブを示します:
SecFilterSelective LOCATION KEYWORD [ACTIONS]
どこの検索の実行を望むか正確に決めることができます。KEYWORD と ACTIONS ビットは SecFilter と同じ物です。LOCATIONビットは更に説明が必要です。LOCATIONパラメータはパイプで分割さ れた一連のロケーション識別子から成ります。例えば:
SecFilterSelective "REMOTE_ADDR|REMOTE_HOST" KEYWORD
これは正規表現を使ってクライアントおよびホスト名のIPアドレスだけを探索するでしょう。可能なロケーションのリストはすべてのCGI変数と更にいくつ かを含んでいま す。ここに、全リストがあります:

いくつかの特殊なロケーションがあります:
更にもっと特別な:
さらに、限られた数の出力特有の変数はApache 2で利用可能です。 :(output buffering is enabled な場合に限り):

Argument filtering exceptions

ARGロケーションと一緒に使用される場合に、ARG_variableロケーション名は反転使用をサポートします。例えば:
SecFilterSelective "ARGS|!ARG_param" KEYWORD
param という名前以外の引数すべてを探索します。

Cookies

ModSecurity はクッキーをフルサポートします。デフォルトのクッキーは、あたかもそれらがバージョン0フォーマットであるかのように扱われるで しょう。しかしながら、version 1 cookies (RFC 2965に定義された物)もサポートされます。version 1 cookies サポートを有効にするためには、SecFilterCookieFormatディレクティブを使用してください:
# enable version 1 (RFC 2965) cookies
SecFilterCookieFormat 1
デフォルトでは、ModSecurity はクッキー名、値のノーマライズを試みません。しかしながら、いくつかのアプリケーションとプラットフォーム(例 えばPHP)がクッキー内容をエンコードするので、クッキーにノーマライズテクニックを適用することにができます。
SecFilterNormalizeCookies On
注記
これはSecFilterNormalizeCookieディレクティブ適用済みです。 ModSecurityバージョン1.8.7より SecFilterCheckCookieFormatディレクティブがサポートされました。最近の変更により1.8.7のこのディレクティブは現在、非 難されています。それは、今までどおり設定中で使用することができますが、何もしないのです。ディレクティブは、1.9.x branchで完全に削除されるでしょう。

Output filering

ModSecurity はバージョン2.x のApache用のアウトプットフィルタリングをサポートしています。デフォルトでは無効になっています。したがって、それを最初に有効にする必要があり ます:
SecFilterScanOutput On
その後、変数 OUTPUT を使用して、好みのフィルタを加えてください:
SecFilterSelective OUTPUT "credit card numbers"
たぶん私のコラムにフォローがあるので見てください。http://www.webkreator.com/php/ 私が無能なPHPの致命的エラーの予防に多少、悩まされた事を知っておいてください。私は長い期間、エンドユーザー達にあふれる、致命的エラーの予防を行 いました。(ここを参照http://www.webkreator.com/php/configuration/handling-fatal-and-parse-errors.html) しかし今は、終了しているので、私は、それについてはもはや心配していません。以下はレスポンスボディでのPHP出力エラーに遭遇すると応答をエラーに取 り替えてカスタムPHPスクリプトを実行しています。(アプリケーション管理者に通知されるようにしている):
SecFilterSelective OUTPUT "Fatal error:" deny,status:500
ErrorDocument 500 /php-fatal-error.html
どの場所にでも、アウトプットフィルターを配置できるが、それらが同時に実行されない事に注意してください。インプットフィルターは Apache によりリ クエストを処理実行する前、一方、アウトプットフィルターは Apache がリクエスト処理を完了した後に実行されます。
注記
skipnext とchain を使ったアクションはアウトプットフィルターでは働きません。
アウトプットフィルタリングは単純なプレーンテキストと HTML 出力に役立ちます。バイナリの内容(例えば画像)に正規表現を適用することはサーバーを遅 くするだけです。デフォルトのModSecurity は content type無し、content type  text/plan,  content type text/html のレスポンスをアウトプットスキャンします。
SecFilterOutputMimeTypesdirectivを使い変更できます:
SecFilterOutputMimeTypes "(null) text/html text/plain"
上記の例は、plain textファイルとhtmlファイルにおいて、ModSecurityがアウトプットフィルターを適用するとともに形成されています。また、ファイルの mime タイプを指定しない場合は"(null)"です。
注記
アプトプットバッファリングを使用すると、ModSsecurity はメモリ内にページ出力の 全体を維持します。それはとても大きく、メモリ消費量はページサイズの2倍強になります。
アウトプットモニタリングは幾つかの状況で有用な特徴ですが、 フールプルーフでは無い事を承知しておくべきです。もしアタッカーがリクエスト処理のフルコントロール下なら、2つの方法でアウトプットモニタリングを回 避できます:

  1. モニターされていないContent-Type を使用する。(全てのContent-Typeをモニターするのは非現実的で適切では無いと推論します)

  2. 何らかの方法でアウトプットをエンコードします。どんな単純な符号化でもモニタリングを騙すに十分です。
1.9時点で、別のアウトプット変数 OUTPUT_STATUS は実装済みです。この変数は、レスポンスのステータス・コードを含んでいます。

Actions

数個のタイプのアクションがあります:

Specifying actions

アクションを記入することができる3つの場所があります。1つは SecFilterDefaultAction ディレクティブで、大部分のフィルターマッチする定 義されたアクションを実行します。
SecFilterDefaultAction "deny,log,status:500"
この例は、カンマを使用して分離された3つの例を定義します。カンマはリスト中のアクションを区別するために使用されます。始めの2つのアクションは両立 する単語から成ります。しかし、3番目のアクションはパラメータを要求 します。アクション名からパラメータを分けるためにはダブルコロンを使用します。フィルター毎のアクションを使用する場合リクエストがフィルターマッチ上 で拒否されるだろうと仮定しています。リクエストを許可に移行したければ、致命的で無いアクションを( "log,pass"のように)明示的にセットしなければなりません。
注記
1.8.6時点で、もしあなたが重大では無いデフォルトアクションを指定したなら("log, pass"など)mod_security初期 設定過程で無視されるでしょう。初期設定過程では重大では無いアクションを許可してリクエストに関する情報を集めます。重大では無いアク ションの許可は多 くのリクエスト断片を見付けられなくします(mod_securityの内部処理の為)。従ってmod_securityが"検出のみ"モードで動作する 事を望むなら暗黙の検証機能をすべて無効にすべきです。(check URL encoding, Unicode, cookie format, byte range)
注記
メタデータアクション (id, rev, msg, severity)と、ルールをコントロールするアクション(skip/skipnext, chain)は、SecFilterDefaultActiondirective に表わせません。

Per-rule actions

さらに、フィルタごとのアクションを指定することができます。両方のフィルタイングディレクティブ(SecFilterと SecFilterSelective)は、オプションのパラメーターとして1セットのアクションを認めます。ルールごとのアクションは最も直近に指定し たSecFilterSignatureアクションディレクティブにマージされます(デフォルト値は log, deny, status:403 )次のルールでマージプロセスを適用します:
  1. プライマリーアクションだけがアクションリストごとに許可されます。ルールごとのプライマリーアクションは、デフォルト・リスト中のプライマ リーアクションを無視するでしょう。

  2. ルール設定ごとに指定されたアクションは、デフォルト・アクション・リスト中の等価なアクションを無視するでしょう。

  3. 制限モード(SecFilterActionsRestrictedを参照)を有効にする場合、メタデータアクションのみルールごとのアク ション・リストに表わすこ とができます。

  4. ルールは設定時(好ましい, 直感的)又は動作時(直感的でない)マージする事ができる。差違について学習する為に読み進めてください。

SecFilterSignatureAction

1.9RC1以降、利用可能な SecFilterSignatureAction ディレクティブは、ルール・セットのメンテナンスをより簡単にします。1.9RC1に先立ち、もしルールごとのアクション・リストを使用したいならば、全 てのアクションリストが完了していなければいけません。例えば、プライマリーアクション、ステータス・コードなどの指定です。これは設定ポリシーからルー ル(アタック検出ロジック)の分離を非常に困難にしました。SecFilterSignatureActionディレクティブは、単一の設定コンテキスト 内に何度も現われることができます。また、直ちに、それに続くルールに当てはまります。例えば:
SecFilterDefaultAction log,deny,status:500

# The rule below will respond with actions
# specified in the context it is executed in.
# You should note that the context a rule is
# executed in is not necessarily the context
# that rule was created in. Through inheritance
# one rule can be executed in many different
# contexts.
SecFilter 000

# Warning rules
SecFilterSignatureAction log,pass
SecFilter 111 id:1
SecFilter 222 id:2

# Error rules
SecFilterSignatureAction log,deny,status:403
SecFilter 333 id:3
SecFilter 444 id:4
# Rule below, too, will reject with status 403
SecFilter 555

SecFilterActionsRestrictedと一緒に使用されると、このディレクティブは設定にサードパーティールール・セットを含ませる事を より簡単にします。

注記
SecFilterSignatureActionディレクティブの値は子コンテキスト中で継承されないでしょう。

Restricting what can appear in the per-rule action list

時折、設定中にサードパーティールールを含みたいと思います。あなたは、そこに許可するアクションを見えるように表わしたいでしょう。 SecFilterActionsRestrictedディレクティブの助けで、これを行う事ができます:

SecFilterSignatureAction log,deny,status:403
SecFilterActionsRestricted On
Include conf/third-party-rules.conf

ルールごとの設定中で唯一許可されたアクションは、制限モードはメタデータ・ルールの id, msg, rev, serverity です。他のルールは暗黙のうちに無視されるでしょう。

Built-in actions

pass

フィルターマッチを続けるリクエストを許可する。フィルターマッチはロギングしたいが、そうでなければアクションは実行させたくない場合、このアクション が役立つ。
SecFilter KEYWORD "pass,log"

allow

このアクションが行なわれた後、リクエストは許可されます。また、他のフィルターは試みられないでしょう:
# stop filter processing for request coming from
# the administrator's workstation
SecFilterSelective REMOTE_ADDR "^192.168.2.99$" allow

deny

フィルターマッチ上の割込みリクエスト処理。もし、statusアクションが使用されなければ、ModSecurityは直接HTTP 500エラー・コードを返します。リクエストが拒否された場合、ヘッダー"mod_security-action"はリクエストヘッダーのリストに加え られます。このヘッダは、使用されたステータスコードを含みます。

status

リクエストを拒否する場合、与えられたHTTPステータスコードを使用します。下記の規則です:
SecFilter KEYWORD "deny,status:404"
起ったならば"Page not found"応答を返します。設定中にある Apache の ErrorDocument ディレクティブが働きます。従って、あなたが以前に与えられたステータス状況に対応する為のカ スタムエラーページを定義しているなら、それがユーザーに表示されるでしょう。

redirect

フィルターマッチすると与えられたURLへユーザを転送します。例えば:
SecFilter KEYWORD "redirect:http://www.modsecurity.org"
この設定ディレクティブは、常にHTTPステータスコード、又は deny キーワードを無視するでしょう。URLにカンマを含んではいけません。

proxy

フィルターマッチするとリクエストは内部リバースプロキシーを通し書き直します:
SecFilter KEYWORD "proxy:http://www.example.com"
このアクションを作動させるには mod_proxy のインストールが必要です。

exec

フィルターマッチしたらバイナリの実行を行います。バイナリへのフルパスを必要とします。
SecFilter KEYWORD "exec:/home/ivanr/report-attack.pl"
このディレクティブは現存のプライマリアクションに影響しません。このアクションは、常にパラメータ無しでスクリプトを呼びだします。しかし環境情報はす べて供給します。通常のCGI環境変数はすべて そこにあるでしょう。あなたはフィルターマッチごとに1つのバイナリを実行できます。実行するとリクエストヘッダーのリストに mod_security-executed ヘッダを加えるでしょう。
注記
あなたはフォークしスレッド化されたプロセス結果中の新しいプロセス中の全ての生存し応答す るスレッドに気づいているべきで す。したがって、フォーキングは、マルチスレッドの オペレーション中には、より大きなオーバーヘッドを招くかもしれません。

log

ログフィルターにマッチすれば Apache エラーログに記録する。

nolog

フィルターにマッチしたらログしない。これは同じログを記録する事を防ぎます。

skipnext

このアクションは、1つ以上のルールをスキップすることを可能にします。特別にリクエストのいくつかのテストを行なう必要がないと確信できるなら、このア クションを使用できます。デフォルトで、アクションは次にあるルールをスキップするでしょう。オプションのパラメータ数値を指定すれば、ルールを何個でも ジャン プすることができます:
SecFilterSelective ARG_p value1 skipnext:2
SecFilterSelective ARG_p value2
SecFilterSelective ARG_p value3
chain

chain

ルールチェーニングは、より大きなテストへ複数のルールをつなぐことを可能にします。チェーンの中の最後の規則だけがリクエストに影響するでしょう。しか し、そこに達するには、それ以前の規則もすべてマッチしなければなりません。ここに、この機能を使用する為の例を示します。

私は、確実なIPアドレスからのみ管理アカウントにログインするように制限したかった。しかしながら、管理ログイン・パネルは他のユーザーと共有されてい ます。そして、このために私は Apache の標準の機能を使用することができませんでした。よって、私はこれら2つの規則を使用しました:
SecFilterSelective ARG_username admin chain
SecFilterSelective REMOTE_ADDR "!^YOUR_IP_ADDRESS_HERE$"
最初のルールは、パラメータとユーザー名が存在し、その値が admin の場合のみ一致します。単にその後、第2のルールは実行され、それは、リモートア ドレスとリクエストした一つのIPアドレスのマッチングを試みる。もし、それがマッチしなければリクエストを拒否します。(感嘆符 "!" から始まる事に注意してください)

pause

リクエストに応答する前に指定されたミリ秒単位で休止します。これで速度を落すと、いくつかのウェブスキャナーを十分に混乱させられる。いくつかのスキャ ナーは休止がすごく長いと、ギブアップするでしょう。
注記
このオプションがコストに跳ね返る事に用心してください。すべてのウェブサーバーのインスト レーションは、常に、サーブできる最 大のリク エストの数という限界で設定されています。長い遅延時間を備えたこのオプションの利用は、脆弱性スキャナーがパラレル(したがって多数)でリクエストを実 行している場合、"自ら" 強制サービス拒否攻撃を作ることになるかも知れません。

auditlog

監査ログにトランザクション情報を記録します。

noauditlog

監査ログにトランザクション情報を記録しません。

id, rev, msg, serverity

これらの4つのアクションはすべて1つのパラメータを個別に受理し、ModSecurityによって出された全てのログメッセージの中のパラメータを再生 します。このアイデアは、 問題分類に有効で、エラーログに、より多くの情報を入れることができます。

注記
これらのアクションは標準ルール上、あるいはチェーンを開始するルール上でのみ使われる。idアクションはどのようなテキストも含む事ができますが、単な る整数を使用する事を推奨します。将来のある時期に、私たちが有効なルールIDとして整数だけを認めるだろうという保証はありません。もし公にルールを公 表するつもりで無ければ、ローカル範囲の1 - 99,999を使用すべきです。これらがローカル範囲です。

mandatory

サブコンテキスト中のmandatory inheritanceにルール又は、チェーンに、ルールにマークするこのアクションを使えます。詳細については filter inheritance のセクションを読んでください。
注記
アクションid は単独利用されるスタンドアローンルール又は、チェーンを開始とするルール上で使用できます。
例えば:

SecFilter 111 mandatory

又は

SecFilter 111 mandatory,chain
SecFilter 222

setenv, setnote

これらの2つのアクションは指定された Apache の環境変数をセットするかアンセットします。利用できる3つのフォーマットが有ります。

名前と値の選択:
SecFilter KEYWORD setenv:name=value
単に名前を選択すると、値は"1"と仮定します:
SecFilter KEYWORD setenv:name
変数名の前に感嘆符を置くことにより既存の variable / note を削除します:
SecFilter KEYWORD setenv:!name

Request headers added by mod_security

可能なところならどこにでも ModSecurity は、リクエストヘッダーに情報を加えられます。スクリプトはそれらを見つけて使用することが可能です。確実にあなたのスクリプトを実行するためにはリクエ ストを拒否しないように mod_securityを設定しなければならないでしょう。

一見、私がこの目的のために、例えば、環境変数の代わりにリクエストヘッダを使用しているのは奇妙かもしれません。環境変数だとよりエ レガントでしょうが、環境変数がそうなっていない間、ErrorDocument ディレクティブ(以下を参照)を使用する実行スクリプトから入力ヘッダは 常に見えているからです。これは加えられたヘッダのリストです:

Logging the request body

ModSecurtyはmod_security-body noteを通ってリクエストボディをエクスポートするでしょう。ロギングの為にこれを使用できます:
LogFormat "%h %l %u %t \"%r\" %>s %{mod_security-body}n
注記
もしもリクエストが、multipart/request-data タイプ(ファイルアップロード)である場合、本物のリクエストボディは、シミュレートされた application/xwww-form-urlencoded の内容と取り替えられるでしょう。

Handling rule matches using ErrorDocument

もし、あなたの設定が HTTPステータスコード500 を返し、カスタムスクリプトが、常にこのコードを出す Apache の設定の場合(例えば ErrorDocument 500 /error500.php )エラー応答の為にあなたのお気に入りのスクリプトエンジンを使用する事ができます。エラーについての情報は環境変数 REDIRECT_* と HTTP_MOD_SECURITY_* にあるでしょう。(ここに記述されてますhttp://httpd.apache.org/docs- 2.0/customerror.html

Making ModSecurity talk to your firewall

ある場合には、特に危険な攻撃又は一連の攻撃を検知した後、同じソースから来る更なる攻撃を防ぎたいと思うでしょう。ファイアウォールを修正することで特 定のIPアドレスから来るトラフィックをすべて拒否することができます。(私は、iptablesで作動するヘルパースクリプトを書いており、ここからそ れをダウンロードできます:http://www.apachesecurity.net)

この方法は結果的に非常に危険なサービス拒否攻撃(DOS)にも成り得ます。例えば、攻撃者は、攻撃を始めるためにプロキシを使用することができます。 Proxyサーバーからのアクセスすべての拒否は正当なユーザー達も全員拒否されるので、非常に危険かもしれません。
ほとんどのプロキシーが情報にオリジナルのクライアントについて記述するようになって以来、私たちはスマートに実際のIPアドレスを見つけることができま す。(これについての情報は http://www.webkreator.com/cms/view.php/1685.html の "Stop hijacking" 以下で利用可能です。)これが有効な間、下記のシナリオを考慮してみてください:

したがって、あなたがプロキシを通ってアプリケーションへのアクセスを許可しないか、有名なプロキシだけを通るアクセスを許可しない場 合のみ、この方法は有用になります。そして、より重要な事は、信頼の構築です。

まだIPアドレスに基づいたリクエストを(警告にもかかわらず)禁止したければ、フィルターマッチングしたら実行される小さなスクリプトを書く必要がある でしょう。スクリプトは、環境変数から攻撃者のIPアドレスを抽出し、次に、IPアドレスを禁止するというiptablesまたはipchainsへの呼 出しを行うべきです。私たちは、mod_securityの将来のバージョンでこれを行うサンプル・スクリプトを含ませるでしょう。

Special Features

File upload support

ModSecurity は multipart/form-data エンコーディングを使ったファイルアップロードをサポートしています。

Choosing where to upload files

ModSecurity は、常に一時ディレクトリーにファイルをアップロードします。SecUploadDirディレクティブを使用して、ディレクトリー を選ぶことができます:
SecUploadDir /tmp
ファイル用ストレージの何処かのプライベートディレクトリを選択するのがベターでWEBサーバーユーザーのみがアクセス可能です。他の場合は、その他の サーバーユーザーはWEBサーバーによってアップロードされたファイルにアクセスできる。

Verifying files

ウェブサーバーアプリケーションを通過することが許可される前にファイルを確認することを外部スクリプトを指定して実行できます。 SecUploadApproveScriptディレクティブはこの機能を有効にします。次の例と同様です:
SecUploadApproveScript /full/path/to/the/script.sh
スクリプトに一つのパラメータを与えられます。 - アップロードされたファイルへのフルパスを指定します。それは何であれファイルとして扱います。処理後に、標準出力に結果を書き出す筈です。結果の最初の 文字が「1」の場合、ファイルを受理します。その他全部と、全体のリクエストは拒否されるでしょう。あなたのスクリプトは休止する部分にエラーメッセージ を記述できます。このエラーメッセージはデバッグログに格納されます。

Storing uploaded files

ウェブサーバによってファイルをアップロードしておくことに決めることができます。単に、設定に次の行を加えてください:
SecUploadKeepFiles On
ファイルはSecUploadDir ディレクティブで指定したディレクトリに置かれます。もしもファイルを選択的に保持したければ使用します。
SecUploadKeepFiles RelevantOnly
これは、適切なリクエストに属するファイルだけを維持するでしょう。

Interacting with other daemons

他のデーモンとの協調動作を許可するには(例えば後述の ClamAV )1.9dev1では、ファイルはグループに読み取りを許可する緩いパーミッションで 作成します。これは、当然、Apache は httpd として、clamav はデーモンとして動作します:
# mkdir /tmp/webfiles
# chown httpd:clamav /tmp/files
# chmod 2750 /tmp/files
ここに設定した場所のフォルダーに user clamav はアクセスします。同様に、どのファイル作成もグループ、所有者 clamavで行われます。SecUploadDir ディレクティブで /tmp/webfiles を適切に指定するのを忘れないでください。

もしあなたが、(フォルダー)内部のファイルの保持を続けるならばウェブサーバーユーザー所有となり、そこに残しておくのは安全でないかもしれません。例 えばモジュール動作するPHPを持ち、信頼していないユーザーを抱えているなら、彼らはファイルにアクセスする事ができるかもしれません。ファイルを root だけが判読可能にし、且つ、場合によっては個別の場所にそれらをすべて移動する為の cron スクリプトの導入を考慮してください。

Integration with ClamAV 

Modsecurity ディストリビューションは mod_securityファイル承認メカニズムが ClamAV で作動することを可能にするユーティリティースクリプトを含んでいます。これは、とりわけ手軽にウイルスを防ぎ、アップロードファイルを通しウェブサー バーに送信する exploitを防ぎます。
#!/usr/bin/perl
#
# modsec-clamscan.pl
# mod_security, http://www.modsecurity.org
# Copyright (c) 2002-2004 Ivan Ristic <ivanwebkreator.com>
#
# $Id: modsecurity-manual.xml,v 1.7 2005/11/01 13:59:55 ivanr Exp
#
# This script is an interface between mod_security and its
# ability to intercept files being uploaded through the
# web server, and ClamAV
# by default use the command-line version of ClamAV,
# which is slower but more likely to work out of the
# box
$CLAMSCAN = "/usr/bin/clamscan";
# using ClamAV in daemon mode is faster since the
# anti-virus engine is already running, but you also
# need to configure file permissions to allow ClamAV,
# usually running as a user other than the one Apache
# is running as, to access the files
# $CLAMSCAN = "/usr/bin/clamdscan";
if (@ARGV != 1) {
print "Usage: modsec-clamscan.pl <filename>\n";
exit;
}
my ($FILE) = @ARGV;

$cmd = "$CLAMSCAN --stdout --disable-summary $FILE";
$input = `$cmd`;
$input =~ m/^(.+)/;
$error_message = $1;
$output = "0 Unable to parse clamscan output [$1]";
if ($error_message =~ m/: Empty file\.$/) {
$output = "1 empty file";
}
elsif ($error_message =~ m/: (.+) ERROR$/) {
$output = "0 clamscan: $1";
}
elsif ($error_message =~ m/: (.+) FOUND$/) {
$output = "0 clamscan: $1";
}
elsif ($error_message =~ m/: OK$/) {
$output = "1 clamscan: OK";
}
print "$output\n";

Upload memory limit

Apache 1x は、リクエストを遮断するために適切なインフラストラクチャーを提示していません。メモリ操作だけでそれらリクエストを格納するのを完全に遮ることは可能 で す。Apache 1xは、メモリ中の multipart/form-data (ファイルアップロード)リクエストを分析するかあるいはそれらを全く分析しない選択があります。( POST processing off を選択する)

Apache 2x では、メモリ中の multipart/form-data リクエストを解析して費やしたいメモリの量を定義することができます。デフォルト値は 60KB です。しかし、限度値は SecUploadInMemoryLimitディレクティブを使用して変更することができます:
SecUploadInMemoryLimit 125000

Server identity masking

よく使われる一つのテクニックは、アタッカーを混乱させ攻撃スピードを落させるウェブサーバー名の変更です。ウェブサーバーは一般的にサーバー・ ヘッダー 中 のすべての HTTPレスポンスでそれらの属性名を送信します。ここは Apache は特に有益で、デフォルトで SeverName と version を送りま せん。しかし、更にサーバーモジュールが、それらバージョン情報を追加する事を可能にします。

通常 Apache ウェブサーバの属性名を変更するには、あなたはソース・コードに入らなければならないでしょう。"Apache名"がどこでハードコード されるか探し、それを変更します、そして、サーバーを再コンパイルします。同じ結果に達するにはSecServerSignatureディレクティブを使 用します:
SecServerSignature "Microsoft-IIS/5.0"
これは完全に動作するのですが、熟練した攻撃者(またはツール)は、ウェブサーバの"フィンガープリント"を採るために他の技術を使用しても良い事に注意 するべきです。例えば、デフォルトファイル、エラーメッセージ、ヘッダーを出力する命令、サーバーが信頼する又は類似したリクエストに答える方 法すべてに本当の属性名を出します。私は、mod_securityの将来のリリースで属性名マスキングのサポートをさらに強化するでしょう。

もし、あなたが Apache シグネチャを変更したらエラーログの奇妙なメッセージによって悩まされます。(いくつかのモジュールはまだ見えます - これはエラーログだけの影響で、外部からは予想どうり動作します):
[Fri Jun 11 04:02:28 2004] [notice] Microsoft-IIS/5.0 mod_ssl/2.8.12
OpenSSL/0.9.6b configured -- resuming normal operations
後述、chrooting のために説明された通りに mod_security がロードするモジュールを最後に実行することを可能にするディレクティブを再度正確に整える べきです。
注記
順番にこのディレクティブを働かせる為には、あなたは Apache.conf の ServerTokens の"全部"を 残す/整える かしなければいけない。
SecServerSignatureディレクティブが公開サーバーのシグネチャを変更するために 使用される時、ModSecurityは識別を可能にす るためにエラーログに実際のウェブサーバーとモジュールのシグネチャを書き込みます。
[Fri Jun 11 04:02:28 2004] [notice] mod_security/1.9dev1
configured - Apache/2.0.52 (Unix) PHP/4.3.10 proxy_html/2.4

Chroot support

Standard approach

ModSecurity は Apache filesystem isolation と chrooting サポートを含んでいます。Chrooting は、ファイルシステムの、特別の部品でアプリケーションプロセスを制限します。しばしば "jail" と呼ばれています。一旦 chroot(change rootの略) オペレーションが実行されると、アプリケーションはもはや "jail" の外に位置するものにアクセスすることはできません。ルートユーザーだけがjailおよび chrooting プロセスの重要な部分を回避できます。そし て、重要な部分は、chrooting プロセス は、jail の内部ではルートに関連付けられる事は何も許可しない(ルート・プロセスあるいは suid ルートバイナリ)そのアイデアは、もし攻撃者がウェブサーバーに 押し入っても、彼が望む行いには同調できないということです。それに、彼自身も"jail"にいるので脱出不能です。アプリケーションは chrooting をサポートする必要はありません。どのアプリケーションでも chroot バイナリを使用してchrooted することができます。
次の行です:
chroot /chroot/apache /usr/local/web/bin/apachectl start
Apache が /chooot/apache 配下にファイルシステムを置き換えた後スタートします。不運にも、事態はそれほど単純ではありません。問題はアプリケーションの典型的な要求でシェ アード・ライブラリ、様々なファイル、他のバイナリが適切に機能することなのです。したがって、それらを機能させるために、要求されたファイルのコピーを 作 り、それらを jail の内部で利用可能にしなければなりません。これは、容易なタスクではありません。( http://penguin.epfl.ch/chroot.html にApacheウェブサーバーのchrootの詳細な命令方法がある)

The mod_security way

先日アパッチを chrooting している間、私はプロセスにうんざりさせられ悟りました。そして、それを単純化する方法を捜し始めました。その結果、 mod_security モジュール自体へ chrooting する機能性を構築しました。単に設定ファイルに1行を加 える必要があります:
SecChrootDir /chroot/apache
あなたのウェブサーバはchrootedに成功するでしょう。単純なこと以外にも、mod_security chrootingは別の利点をもたらします。外部の chrooting と異なり(前述で言及された) mod_security chrooting はjailに存在し追加のファイルを要求しません。chroot呼出しはウェブサーバ初期設定の後に、しかしフォークする前に作られま す。このため、シェアード・ライブラリはすべて既にロードされています。ウェブサーバーモジュールはすべて初期化され、ログファイルが開かれます。あなた は単に jail 内のデータを要求しています。

いくつかのケースがあります。しかし、jail の追加ファイル、そしてそれをいつ必要とするかは、あなたが実行するのがCGIスクリプトなのかシステムバ イ ナリなのかどうかです。それらは自分のファイル要求を持っているかもしれません。そのときこのカテゴリーに入れば、正常なものとして外部の chroot 手 続きを続ける必要があります。しかし、まだ Apache 自体について考える必要はないでしょう。
注記
Apache 2.x の AcceptMutex ディレクティブのデフォルト値は "pthread" です。時々、このセッティングは chroot 機能を使う Apache の働きを妨げます。 Set AcceptMutex は任意の他の設定でこの問題を回避できます。(例えば"posixsem")
もし、あなたが jail 外のログファイルを残すために chroot を形成したならば、Apache は jail の外のファイルに対して ファイル記述子ポインタを持つでしょう。chroot メカニズムは当初はありませんでした。セキュリティとこれに関して心配する多くの人々すべてのためにデザインしました。構成は自分自身で決定 して ください。多少実験的なものとしてこの機能を扱ってください。
注記
もし、あなたのインストールした Apache が mod_ssl を使用するなら、ファイルベースの SSL mutex が使用される場合に jail の外側のログ・ディレクトリーを探す事は不可能でしょう。これは、mod_ssl がスタート時に直ちにログ・ディレクトリー中でロック・ファイルを作成しますが、それをその後、見付ける事ができない場合、失敗します。この問題は他のあ るミューテック・タイプ (例えばSSLMutex sem) を使用するか、jail の内部のディレクトリー中のファイルベース mutex の場所を mod_ssl に伝えることにより回避することができます。(using SSLMutex file://path/to/file)
注記
もし、あなたが、マルチスレッド Apache の chroot の利用を試したいなら、pthread_cancel を働かせるため
に libgcc_s.so.1 のインストールが不可欠です。Apache設定ファイルに Load-File /lib/libgcc_s.so.1 を追記するとこの問題は解決します。

これらApacheの認証が使っているファイルはjail の中ですべてのリクエストで開かれます。

Required module ordering for chroot support (Apache 1.x)

上に言及されたように、chroot 呼出しは他のすべてのモジュールが初期化された後だけ、Apache の初期設定中の特定の瞬間に実行されます。これ は、ModSecurity がモジュールのリスト上で最初でなければならないと言う事です。それを保証するために、次の設定ディレクティブを使用して、 恐らくモジュール順序にいくつかの変更を加える必要があるでしょう:
ClearModuleList
AddModule mod_security.c
AddModule ...
AddModule ...
AddModule ...
最初のディレクティブはリストをクリアします。、mod_security を次に置かなければなりません。続いてあなたが意図するすべての他のモジュール を使用( http_core.c, 以外は常に自動的に加えられるので、心配しなくて良い)。あなたは -l スイッチを使った httpd バイナリの実行により内蔵のモジュールのリストを見つけ出すことができます:
./httpd

注記
Apache のバイナリと jail の外にサポートファイルを置くことに決めたら、"apachectl graceful"と"apachectl restart"コマンドは、もはや使用する事ができないでしょう。それは Apache が jail の外に達する事を必要とします。それは可能ではありません。Apache 2 や、"apachectl stop" コマンドでさえ働きません。将来のリリースでは、私は、置き換わるスクリプトを作成する為に、この問題の関係で働くでしょう。

Required module ordering for chroot support (Apache 2.x)

注記
このステップは、あなたが jail の内部にログファイルを残すつもりならば、必要ではありません。
 Apache 2.xでは、モジュール順序を手動で設定する必要はありません。Apache 2.x が既に内部にサポートモジュールを含んでいます。ModSecurityは、chroot が呼ばれ、いつ働くか Apache2.x に正確に伝えるためにこの機能を使用します。(もし、あなたが問題を抱えているなら知らせてください)

プロセスが Apache 2 の中でどのように始められるかに変更がありました。httpd バイナリ自身が現在のプロセス番号を備えた pid ファイルを作成します。このため、外部の jail に同様なフォルダーで jail の中に Apache を置く 必要があるでしょう。
jail外のApacheを "/usr/local/web/apache"と仮定し、あなたが "/chroot" で、jail を望むなら あなたは、"/chroot/usr/local/web/apache/logs"フォルダーを作成しなければいけません。

スタートした時、Apache はそこに pid ファイルを作成するでしょう。( httpd.conf の中の pid ファイルの位置を変更していないと仮定し、この場合、何を行っているか多 分知っている)

A step-by-step chroot guide

このステップ・バイ・ステップに従えばモジュール・オーダーに悩む事はありません。まず、Apache を普通にインストールします。ここでは、Apache が/usr/local/apache にインストールされ、jail の場所は /chroot/apache と仮定します。 それはサーバー開始と正常に働く事をチェックするのに,とにかく良いアイデアです。
# mkdir -p /chroot/apache/usr/local
# cd /usr/local
# mv apache /chroot/apache/usr/local
# ln -s /chroot/apache/usr/local/apache
ModSecurityにchoroot 実行を命令します:
SecChrootDir /chroot/apache
Apacheをスタートします:
/usr/local/apache/bin/apachectl startssl

注記
chroot 後の jail の場所中に Apache ファイルを残すアプローチの手続きについての記述です。これは 常に働くので推奨アプローチです。そして、chroot から none-chroot への切り替えは非常に簡単です。(単に設定ファイル中の sec-ChrootDir 行をコメントにします)しかしながら、大抵の jail 外部ファイル作成は可能です。しかし、これは更に難しいオプションです。chrootのメカニズムを十分理解する事は、それを正しく行うために必要です。
注記
バージョン1.8以降、ModSecurity が任意の理由で、chrootを実行できない場合、サーバースタートを防止するでしょう。構成段階中に chroot 失敗を検知せず、次にランタイムでそれを検知する場合、エラー・ログ中にそれに関するメッセージを書き、子プロセスから抜けます。これは美しくないかもし れません。しかし、そのような保護を考える場合に、chroot jail の保護なし動作が存在するより良い。

How the mod_security chroot works

あなたのプラットホーム上で問題に遭遇したら、mod_security がどのように chroot を行なうか知ることは有用かもしれません。私たちはサー バーのソースコードは変更しないのでモジュール順序は不可欠です。私たちが克服する必要のある別の問題はモジュールがすべて2回初期化されるという事実で す。初期化動作で1番目の為なのか2番目の為に呼ばれているのか私達には分からないので、これは問題です。(現実には Apache 2x では指定可能しかし Apche1x は不可能)ModSecurityは、第1段階の初期設定過程中にするロック・ファイルを作成使用し、第2段階にそ れを消します。デフォルトでは、ファイルはログフォルダに作られ、関 連ファイルはウェブサーバールートの"logs/modsec_chroot.lock"です。SecChrootLock ディレクティブは、これを他の パスに変 更する為に使います。
注記
バージョン1.8以降、もし ModSecurity が何らかの理由で chroot を実行しない場合、サーバー起動を防止 します。もし、設定中に chroot 失敗を検知せず、その後ランタイムで検知する場合、エラーログ中にそれに関するメッセージを書き込み、子プロセスを終 了するでしょう。これは美しくないかもしれない。しかし、それは、chroot jail の保護なしで実行する既存の保護より良いと思う。

Performance measurement

1.9 dev1 で、私は、mod_security の Apache2 バージョンの性能測定の実験的なサポートを導入しました。性能測定スクリプトはクライアントが遅いリ ンク上にある場合は難しいです。応答が同時に生成され、クライアントに送られるので、2つを分離することは不可能です。性能を測定する唯一の方法は、部分 的な応答を送ることを保留し、完全に生成された場合のみ、送ることです。これは特異な理由が無い場合に正確に mod_security が行います。けれど も、時間を記録する為に一対のコード断片を加える事は重要ではありません。私は3つの同様な断片を加え、結果を Apache notes に格納しました。時間は全て、リクエスト処理のスタートに関しマイクロ秒で与えられます:


カスタムログ中にこれらの値を使いこれを行います:
CustomLog logs/timer_log "%h %l %u %t \"%r\" %>s %b - \
%{mod_security-time1}n %{mod_security-time2}n \
%{mod_security-time2}n %D
ログ中の各エントリは、このように見えるでしょう。
82.70.94.182 - - [19/Nov/2004:11:33:52 +0000] "GET /cgi-bin/modsectest.
pl HTTP/1.1" 200 1418 - 532 1490 13115 14120
上記の例においては mod_security の処理範囲に達するのに532マイクロ秒かかりました。Mod_securityは正規表現を実行するのに 958マイクロ秒(532 - 1490)使い、CGIスクリプトが出力を生成するのに11625マイクロ秒(1490 - 13155)、そして Apache はクライアントへの送信終了までに956マイクロ秒かかりました。

Logging

Debug Log

デバッグ出力がファイルに書き込まれるように選択するには SecFilterDebugLog ディレクティブを使用します。もしパラメータが前方スラッシュで始まらないなら、Apache のホームパス に解釈されます。
SecFilterDebugLog logs/modsec_debug_log
あなたは SecFilterDebugLogLevelでデバックログの詳述をコントロールできる:
SecFilterDebugLevel 4
利用可能な値は次のとおりです:

注記
ModSecurityは内部で9段階のログレベルを使います,しかし、それらはデバッグ目的 だけに役立ちます。

Audit logging

標準の Apache のロギングは、あなたが攻撃者あるいは特定ユーザーの行いをバックトレースする必要がある場合、全く助けになりません。問題なのは、各 リクエストの非常にわずかなサブセットだけがログファイルに書かれていることです。この問題は、ModSecurity の監査ロギング機能で改善 することができます。これらの2つのディレクティブです:
SecAuditEngine On
SecAuditLog logs/audit_log
mod_security でフル監査ログを監査ログに記録させましょう。ここに、リクエストがどのように記録されたのか例があります:
========================================
Request: 192.168.0.2 - - [[18/May/2003:11:20:43 +0100]] "GET /cgibin/
printenv?p1=666 HTTP/1.0" 406 822
Handler: cgi-script
----------------------------------------
GET /cgi-bin/printenv?p1=666 HTTP/1.0
Host: wkx.dyndns.org:8080
User-Agent: mod_security regression test utility
Connection: Close
mod_security-message: Access denied with code 406. Pattern match "666" at
ARGS_SELECTIVE.
mod_security-action: 406
HTTP/1.0 406 Not Acceptable
========================================
最初の行では、Apache から通常得られるものを見ることができます。2行目は、要求を扱うことになっていたハンドラの名前を含んでいます。フルリクエス ト(追加の mod_security ヘッダを備えた)は、セパレータおよびレスポンスヘッダーの後に与えられます(この場合、1行だけあります)空の1行 の後に与えられます。

POSTフィルタリングが On の時、POSTペイロードは監査ログに常に含まれます。実際の応答は含みません(少なくともこのバージョンにはない)。
注記
監査ログデータの扱いには気を付けてください。このファイルは、ネットワーク上で受け取られたフィルターされていないバイナリデータを含んでいるかもしれ ません。そのようなデータは、適切に扱われていなければ、危険かもしれません。(例えば、それはターミナルのエスケープシーケンスを含んでいるかもしれま せん。)
この時に、監査ログにApache 1.xのエラーメッセージ部分の Handler: 行下を記録します。この行は、、常にError: から始まるでしょう。可能な場合は、この機能性が Apache 2.x モジュールに加えられます。
注記
監査ログ・サブシステムはリクエスト・タイムアウトを記録しません。
注記
監査ログ・エントリーの出力ヘッダーは日付及びサーバーを含んでいません。これは、Apache が、モジュールにそれらが到着することを不可能にするレスポンス処理中の最も最後の瞬間にレスポンスにこれらのレスポンス・ヘッダーを加えているからで す

Choosing what to log by response status code

1.9時点で、ModSecurity は SecAuditLogRelevantStatusdirective をサポートします。それは警告またはエラーを引き起こさなかったとしても監査ログするリクエストを記録するため選択的に使用できます。ウェブサーバー上に 配置する単純な通信経路備えたアプリケーションを築く事には特に有用です。例えば、内部エラー又は攻撃発生時に、アプリケーションがHTTPステータス・ コード500で常に答えることを知っていれば、同様に全てのリクエストを記録するためにModSecurityを形成することができます:

SecAuditLogRelevantStatus ^5
このディレクティブは1つのパラメーター(レスポンス・ステータス・コードに対してマッチする正規表現)を受理します。マッチする場合そのトランザクショ ンは、適切と考えられ、且つ、ログされるでしょう。

Unique request identifiers

もし、あなたが Apache の設定に mod_unique_id を加えたなら mod_security はそれを検知、生成する(UNIQUE_ID)環境変数を使用します。エラー・ページに一意のユーザーID を書き、偽正の固定と追跡に使用する事ができます。

Choosing what to log

SecAuditEngine パラメータは、4つの値のうちの1つを受理します:

ModSecurity に動的リクエストを記録させるには、設定に依存するほんの少しの作業が必要です。Apacheは理論上、もし、ハンドラがある場合は、リクエストに対する レ スポンスはハンドラによって生成されます。

それは リクエストに付属した動的な性質であると考えられます。しかしながら、事実上、Apache はハンドラ無しで動的ページをサーバーに形成できる。 ( その後、mime タイプに基づいてモジュールを選ぶ)。もし、PHPで構成した前述したメインディストリビューションならば...これが起こる...例え ば:
AddType application/x-httpd-php .php
動いても全然適切ではない。しかしながら、もし、上記の行を下記に取り替えるならば:
AddHandler application/x-httpd-php .php
PHPは、上手く働き、Apache はリクエストと監査にハンドラを割り当てるでしょう。

1.9dev1時点で 何が適切であるか無いか決定する場合に監査ロガーは応答コードを考慮に入れます。その時の応答コード 4xx と 5xx は妥当なものとして扱われます。これは、(任意の)ウェブ・アプリケーションからのリクエスト監査ロギングを行なうことを容易にします。もし正常 な応答でエラーが生じる場合は応答コードを(例えば)500に変更してください。

New Audit Log Type

新しい監査ログ・タイプはModSecurity 1.9に導入されました。古い監査ログ・タイプはアド・ホックなロギングに役立つままです。新しい監査ログ・タイプはパフォーマンス増大のために導入され ました、(1トランザクション当たり1ファイル作成は、同時リクエスト間の書き込みを同期させる必要を回避します。)ログする情報量を増加させます、そし てリアルタイム監査ログの集合を可能にする。新しい監査ログ・タイプはレスポンスボディも記録することができます。
注記
新しい監査ログタイプはmod_unique_idmodule が有効に働く事が不可欠です。
構成例:
# Yes, we want to use the new format
SecAuditLogType Concurrent

# Directory where the files will be stored
# MUST NOT BE THE SAME AS THE APACHE LOGS FOLDER
SecAuditLogStorageDir /var/www/audit_log/

# The index of all files created
SecAuditLog /var/www/audit_log/index

# Choose what to log . everything (default is ABCFHZ)
SecAuditLogParts ABCDEFGHZ

作成された各監査ログ・ファイルについて、1行のエントリーがインデックス・ファイルに現われるでしょう。
リアルタイム監査ログの集合を実行したい人は、送られた記録するメカニズムによって監査ログ・エントリーに関する情報を得るためにスクリプトを形成するべ きです。
典型的な監査ログ・エントリーはこのように見えます:

192.168.2.101 192.168.2.11 - -[15/Jul/2005:11:56:52 +0100] \
"POST /form.php HTTP/1.1" 403 3 "http://192.168.2.101:8080/form.php" \
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 \
Firefox/1.0.4" G3yTd38AAAEAAAM7BLwAAAAA "-" \
/20050715/20050715-1156/20050715-115652-G3yTd38AAAEAAAM7BLwAAAAA 0 1031 \
md5:dc910f6d647d47b32ae6e47326f0ca42

行の始まりは "vcombined" ログ・フォーマットから始まります。しかし、一方で、次のフィールドを加えます:
典型的な監査ログ・エントリーはこのように見えるでしょう:

- -67458b6b-A- -
[15/Jul/2005:11:56:52 +0100] G3yTd38AAAEAAAM7BLwAAAAA \
192.168.2.11 4236 192.168.2.101 8080
- -67458b6b-B- -
POST /form.php HTTP/1.1
Host: 192.168.2.101:8080
User-Agent: Mozilla/5.0
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://192.168.2.101:8080/form.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

- -67458b6b-C- -
f=111
- -67458b6b-E- -
403 (Response body)
- -67458b6b-F- -
HTTP/1.1 403 Forbidden
Last-Modified: Fri, 08 Jul 2005 14:25:30 GMT
ETag: "decb4-3-34b96a80"
Accept-Ranges: bytes
Content-Length: 19
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html

- -67458b6b-H- -
Message: Pattern match "111" at POST_PAYLOAD
\
[id "1"] [rev "2"] [msg "3"] [severity "4"]
Apache-Handler: application/x-httpd-php
Stopwatch: 1126536042708000 11024 (7276* 7375 9842)

- -67458b6b-Z- -
注記
監査ログデータの扱いには気を付けてください。このファイルは、ネットワーク上で受け取られたフィルターされていないバイナリデータを含んでいるかもしれ ません。そのようなデータは、適切に扱われていなければ、危険かもしれません。(例えば、それはターミナルのエスケープシーケンスを含んでいるかもしれま せん。)
利用可能な監査ログパーツ:

Guardian log

1.9以降、ModSecurity は新しいディレクティブ SecGuardianLog をサポートし、それは、全てのアクセスデータを別のプログラムでロギングし利用する設計です。Apache はマルチプロセス方式で典型的に配置するので、情報共有困難を生じる、目的は、ステートフル方式でリクエストをすべて観察するために単一の外部プロセスを 展開させる事であり、それら保護の補足を提供する。開発段階の外部プロテクション・ツール技術は後のModSecurity リリースの焦点になるでしょう。しかしながら、完全に機能するツールは、Apache httpd ツール・プロジェクトの一部で既に利用可能です。(http://www.apachesecurity.net/tools/) このツールは httpd-guardian と呼ばれ、Denial of Service attack に対して防御するために使用することができます。それは、不快なIPアドレスを動的にブラックリストにして、iptables ベースのファイアウォールと相互作用するブラックリスト・ツール(同じプロジェクトからの)を使用します。httpd-guardian は既に構成されている仮定なら(詳細な指示のためにソース・コードを調査します。)それを展開するには単にApacheの設定に1行を加える必要がありま す:
SecGuardianLog |/path/to/httpd-guardian
デフォルトの httpd-guardian により、1分間に120リクエスト以上、あるいは、5分間に360のリクエスト以上を送信するクライアントに対して防御します。

Custom logging

1.8 以降では mod_security へのリクエストだけを含む Apache のカスタムロギングを使う事ができる。これは ModSecurity が現在の  mod_security-relevan 環境変数を定義する行動を行う。

カスタムログファイルを使用するには、設定に下記(同様な)を加えてください::
CustomLog logs/modsec_custom_log \
"%h %l %u %t \"%r\" %>s %b %{mod_security-message}i" \
env=mod_security-relevant

Miscellaneous Topics

Impedance mismatch

WEBアプリケーションファイアウォールは、アプリケーション及びそのビジネスロジックについての情報なしに通過データを理解しようとする困難なジョブを 行います。それらが提供する保護は、独立したレイヤーを持っている外側のセキュリティより得ます。データ検証が2度行われるので、保護をアプリケーション に触る必要無しで増加させることができます。しかしながら、ある場合には、全てが2度行われるという事実が問題を引き起こします。通信プロトコルが正しく 指定されていないか、デバイスかアプリケーションのいずれかが、仕様に無いことを行うエリアで問題が生じます。最悪の犯罪者は cookie の仕様です。(事実上4つすべて該当:http://wp.netscape.com/newsref/std/cookie_spec.html, http://www.ietf.org/rfc/rfc2109.txt,
http://www.ietf.org/rfc/rfc2964.txt, http://www.ietf.org/rfc/rfc2965.txt.) 多くの場合、現実に可能で、それらの仕様書に言及はありません。彼らが思考を行うのは適正なのでプログラマー達は放置しています。大部分は、cookie が正しく成形されていて、それらのほとんどは問題ではありません。大部分のアプリケーションが、自身が送るクッキーを解析するとい う理由だけで、この問題は更に明白になりません。あなたが、WEBアプリケーションファイアウォール、そして、それを通過しようとする信念の強敵の視 点で考えると、それは問題になります。私が例で説明します。1.8.x branch および 1.8.6 まで、ModSecurity(私は、1.8.7での改良を製作した)はv1クッキーパーサーを使いました。私が意図するパーサを書いた 時、v0およびv1クッキーの両方を扱うことができたので、それは実際に良かった。しかしながら、私は攻撃者的思考を行わないミスを犯しました。 Stefan Esserが私に指摘した、v0とv1フォーマットを識別する間にv0パーサーが多くを見るだろう所でv1パーサーが一つの cookie を見る exploit を作り出す事が出来ました。ここに、あります:
Cookie: innocent=”; nasty=payload; third=”
見てみると、v0 パーサはダブルクォートを理解しません。それは典型的にセミコロンのみを捜し、その結果ヘッダを分割します。同様にパーサーは cookie を見ます"innocent", "nasty", それと "third"。v1パーサは他方で、1つのクッキーだけを見ます - "innocent"。インピーダンスミスマッチはどのようにウェブアプリケーションファイアウォールユーザーおよび開発者に影響するでしょうか?それは 必ず我 々の存続を更に困難にします。でも、大丈夫。- ゲームの一部ですから。開発者はより良くスマートな構文解析ルーチンを組込むために働かなければならないでしょう。例えば、 Modsecurity1.8.7 は、それら2つの cookie パーサーがあり、そして、 ユーザーはどれを使うか決めれます。(v0フォーマット・パーサは現在、デフォルトで使用されています。)しかし、それらの改良は、以降を自動化できない ので、ファイアウォールの使用をもっと難しくするだけです - ユーザーが構成について再思考してください。他方で、ユーザーは、クッキーパーサーに関して考えたくない。HTTPパーツは非常に良く定義されていて常に 回復する。例えば、ヘッダ。個々のクッキーをターゲットとし COOKIE_innocent を使用する代わりに、それら全体のクッキーヘッダをターゲット とて HTTP_Cookie を使用することができます。強敵がその問題を一旦、隠そうとしても、ARGS のような他の変数はすべての変数を直ちに見るで しょう。

Testing

この小さなHTTPテストユーティリティは ModSecurity の事業の一部として開発されていました。それは、サーバーのもとへ巧妙に作られたHTTPリクエストを送り、攻撃が成功裡に検出されたか否か断定する単純 で容易な方法を提供します。パラメータなしでユーティリティを呼び出すと使用法が表示されます:
$ ./run-test.pl
Usage: ./run-test.pl host[:port] testfile1, testfile2, ...
最初のパラメータはサーバーのホスト名指定でポートはオプションです。他のすべてのパラメータは作られたHTTPリクエストを含んだファイルのファイル名 です。

取り扱いをより容易にするために、ユーティリティーはあるリクエストヘッダーを生成します:
望むならばリクエストにそれらを含むことができます。既にある場合は、ユーティリティーはそれらを加えないでしょう。

ここに、HTTPリクエストがどのように見えるかがあります:
# 01 Simple keyword filter
#
# mod_security is configured not to allow
# the "/cgi-bin/keyword" pattern
#
GET /cgi-bin/keyword HTTP/1.0
このリクエストは追加のヘッダ無しで最初の一行から成ります。あなたが望むように、リクエストを複雑にして作成することができます。ここに、POSTメ ソッド使用の一つの例があります:
# 10 Keyword in POST
#

POST /cgi-bin/printenv HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
p=333
ファイルの最初が # から始まる行は、コメントとして扱われます。最初の行は特別であり、それは、テストの名前を含んでいるべきです。ユーティリティはステータスコード200 の結果を予想し、成功した応答を返すでしょう。

他の応答を望むならば、最初の行に予期された応答コードを書くことで、それを告げる必要があります。(どの場所でも良いが)。こんな風に:
# 14 Redirect action (requires 302)
GET /cgi-bin/test.cgi?p=xxx HTTP/1.0
括弧の"requires"キワードは要求されないが、より読み易くする為に推奨する。

Solving common security problems

mod_security の能力の例として、私達は検出と、ほぼ共通したセキュリティ問題の防御方法を実演します。私たちは、問題自体に関して、ここで深 く立ち入らないでしょう。しかし、非常に良い記述が、Open Web Application Security Project's guide において入手可能です。http://www.owasp.org/

Directory traversal

あなたのスクリプトがファイルシステムに関係している場合、一定のメタ文字と組み立てに注意を払う必要があります。例えば文字の組合せ"../"のパスは 1ディレクトリレベル上げるリクエストです。通常のオペレーションでは、リクエストに、この文字の組合せの必要はありません。また、次のフィルター
でそれら を禁止することができます:
SecFilter "\.\./"

Cross site scripting attacks

クロスサイトスクリプティング攻撃(XSS) 攻撃者はHTML or/and Javaスクリプトコードをあなたのウェブページに挿入します。その後、そのコードを読み込んでしまった別のユーザーによって実行されます。これは、期待 しない場所へHTMLを加えることにより行われます。XSS攻撃に成功した結果、攻撃者が、あなたのセションのクッキーを得て、アプリケーションへのフル アクセスを獲得することができます!この攻撃に対する適切な防御はパラメータフィルタリングです。(つまり不快な HTML/Java スクリプトを削除す る)しかし、しばしば、それらを変更せずに、既存のアプリケーションを保護しなければなりません。これは次のフィルタのうちの1つで果たせます:
SecFilter "<script"
SecFilter "<.+>"
最初のフィルターは、<script>タグを備えたJavaスクリプト投入に対してのみ保護するでしょう。二番目のフィルターは、より一般的 で、パラメータ中のどんなHTMLコードも却下します。

このフィルターを適用するのはパラメータ中にHTMLを要求できてしまう多くのアプリケーションで注意する必要があります。 (例えばCMSアプリケーション、フォーラムなど)あなたはこの選択的フィルタリングが使えます。 例えば、一般的な sitewide 規則として2番目のフィルタを持つことができます。 しかし、その後で、次のコードで特定のスクリプトのためにルールを緩めることができます:
<Location /cms/article-update.php>
SecFilterInheritance Off
# other filters here ...
SecFilterSelective "ARGS|!ARG_body" "<.+>"
</Location>
このコード断片は、HTML中に命名したパラメータ"body"だけが許可される。実際には、多分リストにさらに若干の命名したパラメータを加えるでしょ う。

SQL/database attacks

ほとんどのウェブアプリケーションは、今日、データ操作用データベースに極度に依存しています。もしデータベースアクセスを安全に行いたければ、いっそう 注意しなければ、攻撃者はデータベースに任意のSQLコマンドを直接挿入することができます。これは結果的に攻撃者がデータベースから全部の機密データを 読む、変更する、削除する、事ができます。フィルターです:
SecFilter "delete[[:space:]]+from"
SecFilter "insert[[:space:]]+into"
SecFilter "select.+from"
SQLに関連するほとんどの攻撃から保護することができます。これらは例だけです。実際に使用するデータベースエンジンに依存するフィルタを注意深く巧妙 に作る必要があります。

Operating system command execution

ウェブアプリケーションはオペレーションを行なうオペレーティングシステムコマンドを実行するように時折、書かれています。執拗な攻撃者はコンセプトに穴 を探し出し、システムに関する任意のコマンドを実行することを可能にします。
こんなフィルタです:
SecFilterSelective ARGS "bin/"
Unix系のオペレーティングシステム上の様々なディレクトリに存在するバイナリを実行する試みを検知するでしょう。

Buffer overflow attacks

バッファオーバーフローは、プログラムの実行スタックをオーバーフローさせ、それらを実行するためアセンブリ命令を加えるテクニックです。いくつかの状況 では、次のものに似た行の使用によって、このタイプの攻撃を防ぐことができるかもしれません:
SecFilterByteRange 32 126
単にこの範囲のバイト数から成るリクエストを受け入れます。このタイプの保護を使用するかどうかは、あなたのアプリケーション及び使用されるエンコーディ ングタイプに左右されます。

もし、あなたが複数の範囲を支援したければ、正規表現は助かります。あなたはそれに相当する物を使えます:
SecFilterSelective THE_REQUEST "!^[\x0a\x0d\x20-\x7f]+$"

PHP

PHP peculiarities

PHPアプリケーションを保護する目的のModSecurityルールを書く場合に、PHPの特性に気をつける必要があります。規則の設計は多くの場合簡 単です。

以下は私が知っている物のリストです:

Preventing register_global problems

最近、PHP の register_globals 機能の使用がセキュリティ保護問題に結びつくことは広く受け入れられます。しかし常にそうでは無い。(あなたが、この特徴が何か知っていないとすると恐ら く使用していません。だけどぉ、ちょっとまった!、議論を読み取るのは有益です。)実際、register_globals 機能はバージョン4.2.0までディフォルトで有効でした。その結果、多くのアプリケーションがこの機能に依存します。(もっと詳細を見る http://www.php.net/register_globals

できるなら、この機能を使用しないようにコードの要因を分解し書き直すほうが良い。しかし、何かの理由、又は別の物のためにそれをする余裕がなければ、既 知の脆弱性からアプリケーションを保護するために mod_security を使用することができます。コードの問題の部分は、通常このように見えます:
<?php
// this is the beginning of the page
if ($authorised) {
// do something protected
}
// the rest of the page here
?>
攻撃者はURLに補足パラメータを加えて、この長所を逆利用します。例えば
http://www.modsecurity.org/examples/test.php?authorised=1

"?"を使ってパラメータを与えるリクエストすべての明示的な拒否はこうです。すべての攻撃者からアプリケーションを保護するのに十分です:
<Location "/vulnerable-application/">
SecFilterSelective ARG_authorised "!$^"
SecFilterSelective COOKIE_authorised "!$^"
</Location>
上記のフィルターは、空では無い変数"authorised"へのリクエストをすべて拒絶します。さらに私達が<Location>ディレク ティブで実際にそれを必要とするウェブサーバーの部分にのみ制限したフィルターを加えています。

Performance

コストによって提供されたModSecurityの保護。あなたのウェブサーバは多少遅くなり、動作する為により多く のメモリを使用します。

Speed

私の経験では、速度差は重要ではありません。私は、開発の初期の段階でいくつかテストをしました。また、速度差は約10%でした。しかしながら、 ModSecurity 設定で動的なリクエストのみで動かす場合より遅くなる。- 実稼動ウェブサイトにおいては、動的なページに伴う他のタイプのファイル(CSS, JavaScript, images)へのいくつかのアクセスも起こります。影響性能は設定の直接設定の複雑さと関係があります。あなたは個々のリクエストに ModSecurityが仕事に費やす正確な時間の性能測定で改善がされた Apache 2Xバージョンのモジュールを使うことができます。私のテストでは、これは通常2-4ミリ秒(2GHzプロセッサを持ったサーバー上で)でした。
注記
Apache 2 バージョンのモジュールのデバッグログは、Modsecurityの全てのリクエストプロセスと個々のルールの時間を表します。

Memory consumption

リクエストを分析するために、ModSecurity はメモリ中にそれを格納します。大抵の場合、ほとんどのリクエストが小さいので、これはたいしたもの ではありません。しかしながら、それが問題になるのはファイルがアップロードされるウェブサイトの部分です。この問題を回避するには、ウェブサイトのその 部分で ModSecurity の request body buffering off を行います。(これは Apache 1.x バージョンだけの問題です。リクエストが大きすぎて、メモリに格納することができない場合、Apache 2.x バージョン はストレージのディスク上でテンポラリファイルを使います。)どんな場合も、Apache の設定中の様々な制限を調査し設定することは望ましいです。(http: //httpd.apache.org/docs/mod/core.html#limitrequestbody のLimitRequestBody, LimitRequestsFields, LimitRequestFieldsize および LimitRequestLine ディレクティブの記述用を参照)。

Other things to watch for

デバッグ機能は非常に有用です。しかし、それはすべてのリクエスト用のディスクに大量のデータを書きます。そういうものがサーバービジーのボトルネックを 作ります。実働サーバー上でデバッギングモードを使用する理由はありませんので off してください。監査ログ機能は類似する、2つの理由の為に更にボトル ネックを招きます。最初、大量のデータはファイルに書かれています。その次に、ファイルへのアクセスは同期させられるに違いありません。あなたがまだ様々 な監 査ログを作成する監査ログ試みを使用したい場合、各一個のアプリケーションをサーバー上で実行し、同期オーバーヘッドを最小限にします(このアドバイスで は、Apache 2.x バージョンの同期が中央の mutex によって行なわれるのでオーバーヘッドが除かれません)。

Known issues

いくつか既知の問題が有ります:

Important notes

次の注記を読んでください:

Changing the Apache hook at which mod_security runs

デフォルトの mod_security は Apache のリクエストの前処理中の最後の実行可能な瞬間に実行を試みるでしょう。しかし、リクエストが現実に実行される直前です。(例えば、mod_phpによる 処理) mod_securityの最も重要な機能がアプリケーションを保護する事なので、私はこのアプローチを選びました。これに反して、私達は Apache が無防備な一定部分に関して残そうとしています。それら実験を希望する人の為、1.9dev3 mod_securityの時点で、早期の瞬間に実行可能にコンパイルする事ができます。―DENABLE_EARLY_HOOK でコンパイルします。これは実験扱いである事を気に留めていてください。見つけられる違いのうちのいくつかは次のとおりです:
ModSecurityの続くリリースでは、ルール処理が2つの過程に分割する事が考慮されます。一つは出来る限り早期に実行可能とし、もう一つは、出来 る限り後で実行可能にする。

Examples

Parameter checking

正規表現は相当強力に使えます。これはパラメータが0と99999の間の整数かどうかをチェックする方法です。
SecFilterSelective ARG_parameter "!^[0-9]{1,5}$"

File upload

ファイルアップロードするアプリケーションを全部禁止するがサブフォルダーの中では許可する:
# Reject requests with header "Content-Type" set
# to "multipart/form-data"
SecFilterSelective HTTP_CONTENT_TYPE multipart/form-data
# Only for the script that performs upload
<Location /upload.php>
# Do not inherit filters from the parent folder
SecFilterInheritance Off
</Location>

Securing FormMail

任意の受取人へ電子メールを送るためにFormMailの初期のバージョンを乱用することができるかもしれません。
(私は、適切に安全にする事ができる新バージョンがあると聞いています)
# Only for the FormMail script
<Location /cgi-bin/FormMail>
# Reject request where the value of parameter "recipient"
# does not end with "@webkreator.com"
SecFilterSelective ARG_recipient "!@webkreator.com$">
</Location>

Appendix A: Recommended Configuration

以下は推奨される mod_security の最小設定です。
# Turn ModSecurity On
SecFilterEngine On

# Reject requests with status 403
SecFilterDefaultAction "deny,log,status:403"

# Some sane defaults
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding Off

# Accept almost all byte values
SecFilterForceByteRange 1 255

# Server masking is optional
# SecServerSignature "Microsoft-IIS/5.0"

SecUploadDir /tmp
SecUploadKeepFiles Off

# Only record the interesting stuff
SecAuditEngine RelevantOnly
SecAuditLog logs/audit_log

# You normally won't need debug logging
SecFilterDebugLevel 0
SecFilterDebugLog logs/modsec_debug_log

# Only accept request encodings we know how to handle
# we exclude GET requests from this because some (automated)
# clients supply "text/html" as Content-Type
SecFilterSelective REQUEST_METHOD "!^(GET|HEAD)$" chain
SecFilterSelective HTTP_Content-Type \
"!(^application/x-www-form-urlencoded$|^multipart/form-data;)"

# Require Content-Length to be provided with
# every POST request
SecFilterSelective REQUEST_METHOD "^POST$" chain
SecFilterSelective HTTP_Content-Length "^$"

# Don't accept transfer encodings we know we don't handle
SecFilterSelective HTTP_Transfer-Encoding "!^$

Original Reference Manual v1.9 Revision 1 here