(PHP)Smartyでサイニタイズ(サニタイジング)する
WEBアプリケーションでは、XSSとSQLインジェクション対策等のセキュリティリスクを軽減するためにサイニタイズが必須です。
(PHPでの一般的なサニタイズ方法は、(PHP)XSSとSQLインジェクション対策を参照)
さて、テンプレートエンジンに Smarty を使ってて、表示データをアサインして表示するときにサイニタイズする方法です。(出力時のサイニタイズ)
Smartyには、エスケープ処理の機能が実装されており、これを使うことで、HTMLタグを適切にエスケープしてくれます。
使い方はこんな感じです。
○Smartyテンプレート
{$subject|escape:"html"}
コロンの後に何をエスケープするか指定するのですが(デフォルトはhtml)、それぞれどの文字をエスケープするかは下記のような対応となっているようです。
html & " ' < >
htmlall 全ての html エンティティをエスケープ
quotes \'sample\'
mail @→[AT] .→[DOT]
url URLエンコード
hex hex エンコード
しかし、テンプレートにいちいちエスケープの指定をしてると漏れがあった時に大変です。
既定でエスケープするような指定が無いかと探していると、ありました。
それは、Smartyクラス内の $default_modifiers 変数です。
これは、テンプレート内のすべての変数に暗黙に適用される修飾子が格納された配列のようです。
ということで,全ての出力に対して、htmlエスケープをするには下記のようにすれば、OKです。
テンプレート側は、普通に {$test} というようにエスケープする必要はありません。
//Smarty読み込み(ドキュメントルート外のSmartyクラスにアクセス)
require_once('./smarty/libs/Smarty.class.php');
//Smartyオブジェクト作成
//Smartyのディレクトリ設定(キャッシュやテンプレート置き場など)
$smarty->template_dir = "./smarty/templates";
$smarty->compile_dir = "./smarty/templates_c";
$smarty->cache_dir ="./smarty/cache";
//エスケープ
$smarty->default_modifiers = array('escape:html','nl2br');
//アサイン
$smarty->assign("test", "テスト");
//テンプレート表示
default_modifiersは配列なので、下記のように複数指定することも可能です。
下記にするとHTMLエスケープと、改行コードを br タグに変換してくれます。
//エスケープと改行
しかし、エスケープしてほしくない場合もありますよね。
そういう時は、下記のようにすればいいようです。
Smarty ver2の場合
{$var|smarty:nodefaults}
Smarty ver3の場合
{$var nofilter}
バージョンによって違うので注意が必要ですね。
特に、Smarty3での指定方法を見つけるのに時間かかりました。
参考:
Smartyリファレンス:$default_modifiers
Smarty3で$smarty->default_modifiers = array(“escape:’html’”);を指定した場合の|smarty:nodefaults指定方法