IIS7 での拡張された要求のフィルタリング機能の使用
発行日 : 2008 年 9 月 17 日 (作業者 : sudt(英語))
更新日 : 2008 年 10 月 31 日 (作業者 : sudt(英語))
この記事では、拡張された要求のフィルタリング機能の一般的な使用シナリオを示します。これは Windows Server 2008 SP2 に付属していますが、Windows Server 2008 RTM については https://www.microsoft.com/ja/jp/default.aspx からダウンロードできます。これらの機能を構成するための対応する UI がないため、appcmd.exe を使用してこの記事のシナリオを有効化および構成します。
要求の部分で文字列パターンを禁止するルールの作成
IIS の要求のフィルター機能に追加された新機能では、ルールの一覧を作成できます。このルールの一覧を使用すると、HTTP 要求の特定部分と照合されるパターンに基づいて要求を拒否するルールを指定できます。このための主な構成は、 system.webServer/security/requestFiltering セクションの下にある filteringRules セクションです。 拒否状態では、 HTTP エラー 404.19 が表示されます。
例
この例では、サーバー管理者は appcmd.exe を使用してヘッダー "Foo-Header" で文字列 "Foo" および "Bar" をブロックしたいと考えています。
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockFooInHeader']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockFooInHeader'].scanHeaders.[requestHeader='Foo-Header']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockFooInHeader'].denyStrings.[string='Foo']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockFooInHeader'].denyStrings.[string='Bar']"
Config
<configuration>
<system.webServer>
<security>
<requestFiltering>
<filteringRules>
<filteringRule name="BlockFooInHeader">
<scanHeaders>
<add requestHeader="Foo-Header" />
</scanHeaders>
<denyStrings>
<add string="Foo" />
<add string="Bar" />
</denyStrings>
</filteringRule>
</filteringRules>
</requestFiltering>
</security>
</system.webServer>
</configuration>
以下の要求は、ヘッダー Foo-Header に 'Foo' パターンが含まれているため、このルールに適合しません。
GET /iisstart.htm HTTP/1.1\r\n **
Host:localhost\r\n
Accept:*/*\r\n
Foo-Header:Foo--value\r\n
\r\n**
例
この例では、サーバー管理者は任意の ".asp" ページで送信されるクエリ文字列で文字列 "Insert" および "Table" をブロックしたいと考えています。
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockSqlCommands',scanQueryString='True']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockSqlCommands',scanQueryString='True'].appliesTo.[fileExtension='.asp']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockSqlCommands',scanQueryString='True'].denyStrings.[string='Insert']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockSqlCommands',scanQueryString='True'].denyStrings.[string='Table']"
Config
<configuration>
<system.webServer>
<security>
<requestFiltering>
<filteringRules>
<filteringRule name="BlockSqlCommands" scanQueryString="true">
<appliesTo>
<add fileExtension=".asp" />
</appliesTo>
<denyStrings>
<add string="Insert" />
<add string="Table" />
</denyStrings>
</filteringRule>
</filteringRules>
</requestFiltering>
</security>
</system.webServer>
</configuration>
以下の asp 要求は、クエリ文字列に文字列 "Insert" が含まれているため、このルールに適合しません。
GET /iisstart.asp?Query=InsertData HTTP/1.1\r\n **
Host:localhost\r\n
Accept:*/*\r\n
Foo-Header:Foo--value\r\n
\r\n** ****
"denyString" セクションの下に表示されている文字列パターンが含まれていないかどうか、ヘッダー値のみでなくヘッダー全体がスキャンされる点に注意してください。
URL とクエリ文字列のセーフ リストの作成
この新機能を使用すると、定義されているすべての拒否規則をバイパスする安全な URL とクエリ文字列を指定できます。この機能は慎重に使用してください。このセクションで構成を間違えると、悪意のある要求が拒否規則をバイパスする可能性があります。たとえば URL "/my.login.page.asp" が定義された拒否規則をトリガーする場合でも、この URL を常に許可したい場合は、以下のように構成を追加して許可することができます。この機能は、 system.webServer/security/requestFiltering セクションの下にある alwaysAllowedUrls と alwaysAllowedQueryStrings を使用して構成できます。
例
次の例では、appcmd.exe を使用して "Login.asp" ページをホワイト リストされた URL として、および "Allow=true" をホワイト リストされたクエリ文字列シーケンスとして構成します。
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"alwaysAllowedUrls.[url='Login.asp']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"alwaysAllowedQueryStrings.[queryString='Allow=true']"
Config
<configuration>
<system.webServer>
<security>
<requestFiltering>
<alwaysAllowedUrls>
<add url="Login.asp" />
</alwaysAllowedUrls>
<alwaysAllowedQueryStrings>
<add queryString="Allow=true" />
</alwaysAllowedQueryStrings>
</requestFiltering>
</security>
</system.webServer>
</configuration>
URL が有効な URL として受け入れられるには、先頭の '/' が必要です。ユーザーがクエリ文字列 'session<1' を許可したい場合は (許可しなければ定義された拒否規則がトリガーされます)、以下のように構成を追加して許可することができます。 クエリ文字列の先頭に '?' を指定する必要はありません。
URL シーケンスの拒否一覧の作成
すべての要求の URL シーケンスの一覧を拒否するには、 denyQueryStringSequences セクションを作成し、要求の URL で許可しない文字列の一覧を追加します。この拒否一覧は大文字と小文字の区別がなく、形式 %XX のエンコードされた値を許可します (XX は 16 進数字)。 拒否状態では、 HTTP エラー 404.18 が表示されます。
例
たとえば、".." または "./" シーケンスを持つ URL を拒否する場合、appcmd.exe コマンドは次のようになります。
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"denyQueryStringSequences.[sequence='..']" appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"denyQueryStringSequences.[sequence='./']"
Config
<configuration>
<system.webServer>
<security>
<requestFiltering>
<denyQueryStringSequences>
<add sequence=".."/>
<add sequence="./" />
</denyQueryStringSequences>
</requestFiltering>
</security>
</system.webServer>
</configuration>
以下の要求は、クエリ文字列に ".." が含まれているため、このルールに適合しません。
**GET /iisstart.htm?..HTTP/1.1\r\n
Host:localhost\r\n
Accept:*/*\r\n
\r\n
エスケープされたクエリ文字列とエスケープされていないクエリ文字列の両方のチェック
" system.webServer/security/requestFiltering" セクションの unescapeQueryString 属性を使用して、このパターンのエスケープ バージョンとエスケープされていないバージョンの両方をスキャンしたい場合があります。
例
そのため、<script> シーケンスがエスケープされた http://www.foo.com/id=%3C%53%43%52%49%50%54%3E のような要求を送信する場合は、このクエリ文字列のエスケープされていないバージョンもチェックします。 appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /unescapeQueryString:"True"
Config
<configuration>
<system.webServer>
<security>
<requestFiltering unescapeQueryString="true">
<denyQueryStringSequences>
<add sequence="script" />
</denyQueryStringSequences>
</requestFiltering>
</security>
</system.webServer>
</configuration>
これは、クエリ文字列のパターンチェックを 2 回実行します。1 回は生のクエリ文字列に対して、もう 1 回はエスケープされていないクエリ文字列に対してです。