Apache 1.3.12 文字化け問題

Last update: 2000/6/23

結論からいえばブラウザ (Netscape 4.x) が一番悪い。Apache 側の対応としても考えるべきところはあるが。

目次

現象

Apache 1.3.12 にアップグレードしたとたん、一部のブラウザが文 字化けを起こす、という現象が発生するようになった。

この文字化けは「常に発生」というわけではなく、ある一定の条件 のもとで発生する。メーリングリストでのレポートなどによれば、そ の現象は、たとえば、以下のような場合にみられるようである。 [1]

  1. Apache の設定ファイル (httpd.conf や .htaccess など) の Redirect や RedirectMatch など、「他のURLに飛ばす」機能を使っ て、特定の URL から他の URL に「飛ばす」指定を行なった場合

  2. http://www.example.com/~joe のような URL をブラ ウザに指定して http://www.example.com/~joe/ を 表示させる、といった場合

  3. 「AuthType Basic」などでユーザ認証を行ない、認証後に表示される ページ

いずれも、結果として表示されるページの HTML に META タグを使って

        <META HTTP-EQUIV="Content-type"
        CONTENT="text/html; charset=ISO-2022-JP">
      

のように charset を明示して書いておいてもそれをブラウザは無視して、 ISO-8859-1 として表示してしまう、というものである。

ただし、mod_mimeAddCharset 機能などを使って、飛び先のページをサーバから送り 出す際、その HTTP レスポンスにおいて

Content-Type: text/html; charset=ISO-2022-JP

のように、charset を HTTP で明示させている場合には化けない。たとえば今ご覧になっているこのページみたいに。

また、化けるといっても、すべてのブラウザで問題があるわけではなく、 Netscape の version 4 系列での問題の発生が確認されており、Internet Explorer や Netscape の ver.3 や開発中の Mozilla など、他のブラウザ では問題がない。


[1]
Apache の設定ファイルの ErrorDocument ディレクティブで
ErrorDocument 404 "ファイルがみつかりません
などと日本語を書いてエラーメッセージの本文を変えた場合 というのもあるが、これはちょっと別の話

原因

この問題は 2 つの要因によってひきおこされている。

Cross Site Scripting Bug への Apache の対応

Apache の 1.3.12 から、Redirect (301 Moved Permanetly、302 Moved Temporarily) や 401 (Unauthorized) などをクライアント (ブラウザ) に送るための処理を行なう Apache の ap_send_error_response() というルーチン内において、 charset=iso-8859-1 が強制的にセットされるようになった。

つまり 301 や 401 などの HTTP レスポンスが 1.3.11 までは

          Content-Type: text/html
        

だったのが、1.3.12 から

          Content-Type: text/html; charset=iso-8859-1
        

に変更された。

Apache 1.3.12 において A. のような変更が加えられたのは Cross Site Scripting Bug と呼ばれるセキュリティ上の問題への 対応のためである。この問題については CERT による勧告 [1]や、Apache としての対応 [2]を参照。

なお、Debian GNU/Linux (potato) の Apache 1.3.9 については、 1.3.12 で加えられた変更が独自に適用されている。これは securtiy 上の問 題であるからである。同様に、1.3.12 以前の版でも同様の対処が行なわれて いる場合があるなら、この問題は発生する。

Netscape 4.x の charset の扱いについてのバグ

301 や 401 の後に表示するページの META タグにいかなる charset が設定されていても、そのページ直前の (301 や 401 の) HTTP レスポンスで返された charset のほうを見てしまう、という バグが Netscape 4.x にはある。リロードした場合など、キャッシュ から読みこむ場合にはMETA タグのほうを読みにいくので問題はな い。

これついては Netscape 4.x の問題といえるし、一番の原因だろう。


[1]
CERT Advisory CA-2000-02
Malicious HTML Tags Embedded in Client Web Requests
http://www.cert.org/advisories/CA-2000-02.html
[2]
Cross Site Scripting Info
http://www.apache.org/info/css-security/

CSS バグについては セキュリティホール memo - 2000.02.07
Cross-Site Scripting問題とは? などが参考になります。

ところで CSS 対応でナゼ charset=iso-8859-1 などを付けるよう にしたのか、といえば、この charset 情報を元にサーバより送られ た HTML ドキュメントの validation を行ない、不審なものを実行し たりするのを避ける、ということのようです。たぶん。あと、 HTTP/1.1 的には charset パラメタは必須、でしたっけ。

対応

  1. 世の中から buggy なブラウザが消えることを待つ (ほら、Netscape 4.x って CSS のバグは多いし...。がんばれ Mozilla)

  2. Apache にパッチを当てて、 ap_send_error_response()iso-8859-1 を削る。ちょっと後向きだけど

  3. Apache にパッチを当てて、 ap_send_error_response()iso-8859-1iso-2022-jp などに変 える

  4. Netscape 4.x は iso-2022-jp を「文字コード自動 判定(日本語)」として処理するようなので、飛び先 URL が日本語 のページならそれなりにうまくいきそう。

    また、「ウチのサイトは Shift_JISオンリー」とか、「飛び先はす べて把握できる」なら問題ないかも

  5. Apache にパッチを当てて、ap_send_error_response() の 後に読みこまれるであろう HTML の charset を推測して charset=??? をセットするパッチを作る

    同じサイト内ならともかく、他所にあるサーバに飛ばしてたら どうする?

  6. AddCharset などを使って、つねに charset= のヘッダを 付けるように心がける

  7. AddCharset と ErrorDocument を使って、30x や 40x 系のレス ポンスに対し、charset=iso-2022-jp などのヘッダの付いたドキュ メントを返すようにする

下記に示すメーリングリストでの議論を参考にしてください

参考

Apache ML

以降の 3 つのスレッド

FreeBSD Q&A 1650

charsetパラメタの勧め: HTMLにおける文字符号化スキームの明示 方法

AddCharset extention patch for mod_mime module

FIXME: ところどころ説明なしに使っている語句がある のが...。Apache MLのスレッドはざっと読んだだけで、ちゃんと 読めてないかも。自分自身で内容の検証もしてないし...

FIXMEというかTODO: Apache 2.0αでの charset まわ りのハンドリングについての事情や、Apache 1.3.12 での charset ま わりの他のバグについての記述もしたい。

[戻る]