IISのログファイル文字コード

気がつけばもう9月。結局8月は完全にサボってしまった。夏休みやらなんやらでどうも書く気になれず、これといったネタもなかった。これ以上、間を空けるわけにはいかない!ということで、掲題について書いてみる。

IISのログファイルの文字コードは、IIS7からデフォルトでUTF-8になった。もちろんANSIにも変更できるし、IIS6でもUTF-8に変更することができた。実はログパーサー的なもの(ログファイルをスキャンして攻撃痕跡はないかとか、いろんな統計情報を収集したりするもの)をつくる必要があって、このファイル文字コードを気にする必要があった。ファイルをUTF-8として開くのかANSIで開くのか...これは開発する上で非常に重要なことだ。

開発環境によって内部的な文字コードは異なるが、少なくともファイルを開く前にそのファイルがどの文字コードで記述されているかを知っておく必要がある。もちろん、自動判別機能をつけられればそれにこしたことはないんだが、あまたある文字コードにすべて対応するのは非現実的だ。

Webサーバのログなんて、ASCII部分だけ見ればよいかもしれないが、たとえばSQLインジェクションなんかを受けた際に500エラーで返る場合がある(というか攻撃者はそれを狙っている)。このときODBCなどから出力されるエラー文字列がログファイルに出力されるがこれがとても意味をもつことがある。実際にエラー文字列に個人情報が含まれているログを見たことがある。



でまあ、そんなこんなで、実際にIIS7で出力されるログファイルを確認してみた。

■IIS7のログファイルでUTF-8を選択(u_ex090901.log)
2009-09-01 07:54:16 192.168.11.218 GET /index.htm aaa=ああああああ 6530 - 192.168.11.199 Mozilla/4.0+(compatible;+MSIE+8.0;+Windows+NT+5.2;+Trident/4.0;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729) http://192.168.11.218:6530/index.htm?aaa=縺ゅ≠縺ゅ≠縺ゅ≠ 

■IIS7のログファイルでANSIを選択(ex090901.log)
2009-09-01 08:06:54 192.168.11.218 GET /index.htm aaa=ああああああ 6530 - 192.168.11.199 Mozilla/4.0+(compatible;+MSIE+8.0;+Windows+NT+5.2;++Trident/4.0;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729) http://192.168.11.218:6530/index.htm?aaa=縺ゅ≠縺ゅ≠縺ゅ≠ 


両者とも全く同じものが出力される。クエリストリングである「ああああああ」の部分はSJISリファラである化けている部分はUTF-8でいうところの「ああああああ」だ。違いがない。ODBCエラーを発生させてエラーメッセージを見てみた。

■IIS7のログファイルでUTF-8を選択
2009-09-01 08:24:08 192.168.11.218 GET /asptreebbs11/treebbs.asp |32|80004005|[Microsoft][ODBC_Driver_Manager]_データ_ソース名および指定された既定のドライバが見つかりません。 80 - 192.168.11.218 Mozilla/4.0+(compatible;+MSIE+8.0;+Windows+NT+6.0;+Trident/4.0;+SLCC1;+.NET+CLR+2.0.50727;+.NET+CLR+3.5.30729;+.NET+CLR+3.0.30729) 500 0 0 1250


日本語の部分はSJISだ。これはメッセージの発行元であるODBCSJISでメッセージを出力しているからだろう。結局のところ、UTF-8ANSI、どちらを選択しても、リファラも含めて入力された文字コードを素直にログに出力しているようだ(これはフォレンジックという意味からは正しいのかもしれない)。つまり、ファイル内で文字コードが混在することになる。じゃあIISのファイル文字コードの設定はなんのためにあるのか?何に違いがあるのか?

よく分らなくなってきた。

次に、ためしに日本語のファイル名のhtmを公開しブラウザよりアクセス、ログを確認したところ「cs-uri-stem」の部分(パラメータ部分を除いたURL)に違いがみられた。

■IIS7のログファイルでUTF-8を選択
2009-09-02 01:10:30 192.168.11.218 GET /繝・せ繝・htm - 6530 - 192.168.11.151 Mozilla/4.0+(compatible;+MSIE+8.0;+Windows+NT+5.2;+Trident/4.0;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729) - 200 0 0 1875

■IIS7のログファイルでANSIを選択
2009-09-02 01:14:14 192.168.11.218 GET /テスト.htm - 6530 - 192.168.11.151 Mozilla/4.0+(compatible;+MSIE+8.0;+Windows+NT+5.2;+Trident/4.0;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729) - 200 0 0 1015

ちゃんとファイル文字コードの設定に合わせて「cs-uri-stem」の部分が変化した。
次にリファラが「http://localhost/テスト.htm?aaa=テストテストテスト」となるようなリクエストを投げ、ログを確認した。

■IIS7のログファイルでUTF-8を選択
2009-09-02 01:29:54 192.168.11.218 GET /繝・せ繝・htm - 6530 - 192.168.11.151 Mozilla/4.0+(compatible;+MSIE+8.0;+Windows+NT+5.2;+Trident/4.0;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729) http://localhost/繝・せ繝・htm?aaa=繝・せ繝医ユ繧ケ繝医ユ繧ケ繝・304 0 0 1171

■IIS7のログファイルでANSIを選択
2009-09-02 01:26:40 192.168.11.218 GET /テスト.htm - 6530 - 192.168.11.151 Mozilla/4.0+(compatible;+MSIE+8.0;+Windows+NT+5.2;+Trident/4.0;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729) http://localhost/繝・せ繝・htm?aaa=繝・せ繝医ユ繧ケ繝医ユ繧ケ繝・304 0 0 0


両方ともUTF-8で出力された。うーむ。ちなみに、UTF-8ログファイルにBOMはついていない。

MSのIISログファイルの文字コード設定については以下のような記述がある。

ログ ファイルのエンコード方式を UTF-8ANSI から選択します。

シングルバイトおよびマルチバイトの文字が同一の文字列に混在する場合は [UTF-8] を選択します。 このエンコード方式では、英語以外の言語の W3C 拡張形式、IIS 形式、NCSA (National Center for Supercomputing Applications) 共通形式などのテキスト ベースのログを読み取ることができます。 また、Web サーバーで、サーバーの既定のコード ページによってサポートされていない言語または方言で URL を処理する場合、ログ内容に対して UTF-8 エンコード方式を有効にする必要があります。

既定で、IIS は、サーバーの既定のコード ページ以外のコード ページで URL の処理を試みます。 セキュリティの観点からも、攻撃により UTF-8 の URL が既定のコード ページに正しく変換されない可能性があるため、UTF-8 形式を有効にしておく必要があります。


うーむ。何を言っているのか...理解力がないのでいまいち飲み込めない。つぎのような記述も。

"UTF-8" は、シングルバイト系およびマルチバイト系の文字を同一の文字列で混在させることができるエンコード方式です。英語以外の言語でテキストベースの (W3C 拡張、IIS、および NCSA 共通) ログ ファイルを読み取る場合、UTF-8 形式を有効にすることができます。たとえば日本語のシステムで中国語の URL を処理する場合など、ネイティブ サーバー コード ページ以外の言語で URL を処理する場合にも、UTF-8 形式が必要になります。また、既定で IIS 6.0 は、サーバーの既定のコード ページ以外のコード ページで URL の処理を試みるので、セキュリティ上の理由からも、UTF-8 形式を有効にしてください。UTF-8 形式の URL による攻撃を受けた場合、既定のコード ページに正しく変換されないこともあるので、UTF-8 形式を有効にすることは、セキュリティに対する適切な方法です。

つまり、こういうこと?
たとえば(あまりありえないと思うが)、(/テスト/テスト.aspx)に対して、UTF-8エンコードしたクエリ(t=パラメータ)を送信した場合、ANSIログ設定の場合、「cs-uri-stem」の部分(/テスト/テスト.aspx)は「SJIS」で出力され、「cs-uri-query」部分(t=パラメータ)は「UTF-8」で出力され、リファラ部分(ついている場合は)は「UTF-8」で出力されることになる。これでは、1行に複数の文字コードが含まれることになり(単にテキストエディタで開いた場合はどっちかが文字化けすることになり)、フォレンジック調査で効率が悪いと言っているのか??

それを「セキュリティの観点」というにはやや大袈裟な気がする.....。パラメータの部分は何もUTF-8でくるとは限らんし(EUCも大いにありうる。Yahooオークションなんか。).....。