平々毎々(アーカイブ)

はてなダイアリーのアーカイブです。

Re:htmlspecialcharsに関する残念なお知らせ

<追記 date="2009/10/10">
岩本さんはレポートを2つ上げていたのだが
http://bugs.php.net/bug.php?id=49785
http://bugs.php.net/bug.php?id=49814
1つ目の方で対応してもらえたようです。よかった。

私はPHPはぜんぜん詳しくないし、OSSへのバグレポートの経験は1回しかないので、はずしているかもしれない。
htmlspecialcharsに関する残念なお知らせ - 岩本隆史の日記帳(アーカイブ)
外国語ならなおさら、できる限りのことをしないと伝わらない – 秋元

こんな感じの内容だったらよかったのかな?せっかくいろんな人が検証したりしてたのに無視されるのももったいない。

PHPのhtmlspecialchars関数について、UTF-8以外の文字エンコーディングでは妥当性チェックが不充分であり、場合によってはXSS攻撃が可能になる。

挙動

PHP5.2.5以降、UTF-8において部分的なマルチバイト・シーケンスを受け付けないような変更が入った。

  1. 第3引数が"UTF-8"の場合
    1. 冗長表現は不正なシーケンスと見なさず、記号をエスケープした文字列を出力する
    2. それ以外で不正なシーケンスがあれば、出力は空になる
  2. 第3引数がUTF-8でないマルチバイトエンコーディング(Shift_JIS, EUC-JP)の場合
    1. 冗長表現は存在しない
    2. 文字列末尾に不正なシーケンスがあれば、出力は空になる
    3. 文字列途中に不正なシーケンスがあれば、そのまま出力される(再現コードを添付)
    4. 第3引数がShift_JISで、第1引数が1バイトの不正なシーケンス(\xf0 - \xfc)だった場合、そのまま出力される(再現コードを添付)
期待する動作
  • 第3引数がUTF-8でないマルチバイトエンコーディングで、第1引数の文字列途中に不正なシーケンスがあれば、出力は空になる
  • 第3引数がShift_JISで、第1引数が1バイトの不正なシーケンス(\xf0 - \xfc)だった場合、出力は空になる
修正すべき理由
  • 多くの国で、UTF-8以外のマルチバイトエンコーディングが広く用いられている。
  • htmlspecialcharsの挙動がUTF-8とそれ以外のマルチバイトエンコーディングとで変わるべきではない。
  • htmlspecialcharsが不正なマルチバイト・シーケンスを受け付けないことを期待してコーディングしたが、実際には不正なシーケンスが通過してしまう場合、XSSの原因となりえる。
  • なお、このレポートは#43896とは正反対の意見である。すなわち、不正シーケンスであれば必ず出力を空に「するべし」という意味である。
提案パッチ

(コードを添付)