2011年12月10日土曜日

PHP5.4でのhtmlspecialcharsの仕様変更とセキュリティ

さてさて、PHP5.4 Advent Calendar 2011の10日目を担当する瀬戸内○態クラスタphp部門代表、@soudai1025です。

昨日は@srea2431さんがphp5.4で@(エラー制御演算子)はどう進化したのか?という素晴らしい内容でしたので今日はあっさりざっくりうっすらとphp5.4のhtmlspecialcharsの話したいと思います。

そもそもhtmlspecialcharsを使ってない人のために関数の説明をこちらのサイトから引用してきました。
簡単に言うと
htmlentities -- 適用可能な文字を全てHTMLエンティティに変換する
htmlspecialchars -- 特殊文字を HTML エンティティに変換する
こんなところかなと思います。

ただこちらのサイトにも

htmlspecialcharsの第三引数は、今のところ指定するメリットは無い。

と書いてありますがこれ罠です。
詳細は徳丸浩さんがブログ「PHP5.4のhtmlspecialcharsに非互換問題」で述べていらっしゃいます。
そもそも個人的には不正な文字エンコーディングを利用した攻撃を防ぐためにたとえUTF-8だとしても第三引数も指定する方が良いと思います。

で仕様変更で罠はわかったけどそもそも中でなにやってんの?って人。
良いブログ見つけてきましたよw

htmlentities() と htmlspecialchars() の違い

といわけで文字を出力するときは

1 htmlspecialcharsでエスケープ
2 ENT_QUOTESの引数を付ける!
3 第三引数には文字コードを指定する

ということを忘れずにやってくださいね!!
えっお前は他人の引用してるだけじゃん?って声が聞こえてきましたね。
まさにそのとおりです(キリッ
なので更に引用で大垣さんのセキュリティの基礎の話もしときます。

1 入力時にValidate
2 出力時にエスケープ
3 制御時はベストプラクティス

この話はこちらに資料があります。

ついでに自分はこのエスケープを

foreach ($parameter as $key => $get_data) {
    ${$key} = htmlentities($get_data, ENT_QUOTES, 'UTF-8');
}

としたりしています。
これは簡単に説明すると$parameterに連想配列を突っ込んでたらkey名の変数としてエスケープ後に入れてます。
用途によっては配列に入れなおして戻り値として返すメソッドにすればより使いやすくなると思います。
例えば

foreach ($_POST as $key => $get_data) {
    ${key} = htmlentities($get_data, ENT_QUOTES, 'UTF-8');
}

とかすると$_POST['hoge']の中身がエスケープされて$hogeに格納されるって感じです。

というわけでhtmlspecialcharsの仕様変更から処理内容、そして簡単な使い方でした。
それではツッコミお待ちしております!

また明日は@tpyamamotoさんです。
引き続きPHP5.4 Advent Calendar 2011をお楽しみください♪