web-dev-qa-db-ja.com

PHP:クライアントからISO-8859-1(またはその逆)として表示される文字セットの不一致(htmlentities UTF-8)の場合

短い質問:

質問:サーバーがHTMLエンティティをUTF-8として実行しても、クライアントが結果をISO-8859-1として表示する場合、セキュリティの脆弱性が発生する可能性はありますか?

前提:1つの一貫した文字セットが使用されている場合、脆弱性は存在しません


詳細な質問:

質問:サーバーのHTMLエンティティがISO-8859-1文字列をUTF-8として扱う場合、セキュリティの脆弱性が発生する可能性はありますか? (そしてクライアントは結果をISO-8859-1として解釈しますか?)

(例:$results = htmlentities($iso_8859_1_string, ENT_QUOTES, "UTF-8")

すべてが1つの文字セットエンコーディングだけが一貫して使用されている場合に脆弱性が発生しないようにコード化されていると仮定します。 ($ results =空の文字列の場合は無視されます)。

おそらく、_$iso_8859_1_string_に値が含まれている可能性がある場合、結果は無効なUTF-8(および ""を返す)または有効なUTF-8として処理されます。有効なUTF-8の場合、UTF-8シーケンスは期待どおりにエスケープされますが、ISO-8859-1として結果を解釈するクライアントで結果はどのように表示されますか?文字の結果、0〜127の範囲が期待どおりにエスケープされ(「US-ASCII」と同じ)、一部の文字はhtmlエンティティに解決され、期待どおりに表示されます。 htmlエンティティに解決されない、128以上の範囲に有効なUTF-8文字がありますか?クライアントは文字化け/文字化けしたテキスト/シンボルの束を表示するだけで、Webブラウザーにコードを実行させたりコード実行コンテキストに切り替える原因となる文字は表示されませんか? (例えば、「<」「>」記号などのタグ文字がない)? ($ resultsが「コンテンツコンテキスト」に置かれ、「属性値」または「スクリプト」本体に置かれないと仮定します)。

これは正しい考え方ですか?


その逆のケースをすでに解決していると思います(つまり、サーバーのhtmlエンティティUTF-8文字列はISO-8859-1として、クライアントは結果をUTF-8として解釈します)

(例:htmlentities($utf8_string, ENT_QUOTES, "ISO-8859-1")

回答:私の推測では、クライアントにセキュリティの脆弱性はない(ISOとしてのHTMLエンティティの場合->クライアントはUTF-8として読み取る):

  • ISO-8859-1では、次の範囲の文字:

    • 0-127(US-ASCII):UTF-8とまったく同じ方法でエンコードされます。
    • ISO-8859-1の160-> 255はすべてHTMLエンティティとしてエンコードされ、
    • 128-159文字の範囲だけを残します...しかし、WikipediaのUTF-8仕様によると、 http://en.wikipedia.org/wiki/UTF-8#Description 、すべてUTF-8 128以上の範囲にあるバイトはすべて、常に192以上の「先行バイト」と、128以上の範囲にある「継続バイト」を構成する「マルチバイトシーケンス」の一部です。したがって、htmlentities($utf8_string, ENT_QUOTES, "ISO-8859-1")は、有効なマルチバイトシーケンスを生成するためにUTF-8が必要とする「先行バイト」を出力できませんでした。したがって、この範囲の文字はUTF-8では? (無効な文字)「先行バイト」が表示されないため。

これは私の反対方向への疑問を解決すると思います。


実際の状況:A PHP 5.3.xサーバーは、ISO-8859-1をデフォルトのエンコーディングとして使用します。PHP 5.4、UTF- 8がデフォルトのエンコーディングです http://php.net/htmlentities 。すべてのUTF-8またはすべてのISO-8859-1環境でコードが正しく機能するかどうかを確認したい、およびエンコーディングのミス/ミスマッチによって引き起こされる自動セキュリティホールがないことを確認します。

これらの特定のケースでは、ユーザビリティのみが影響を受け、セキュリティは影響を受けないので安心できます。

11
user2533809

私の知る限り、セキュリティ上の問題はありません。

HTMLの「危険な」文字(より小、より大、アンパサンド、一重引用符、二重引用符)はすべて、UTF-8およびISO-8859-1(および事実上他のすべてのエンコーディング)で同じバイト値を持っていますUTF-16、UTF-32、およびEBCDICを除いて、遭遇します。その結果、1つのエンコーディングでエスケープすると、他のエンコーディングでもエスケープされます。

これが当てはまる理由は、UTF-8とISO-8859-1を含む文字エンコーディングの大部分が「ASCIIと追加の文字」であり、HTMLドキュメントの構造はASCIIエンコードの部分。

4
Mark