相変わらず HTML::Template を多用しているのだが。
単純に
<TMPL_VAR name="hoge">
として値を展開すると、その値がそのまま出力される (当たり前だ)。 が、ここで不用意に CGI を作る人がいて、
$tp = HTML::Template->new(***); $query = CGI->new; $tp->param( hoge => $query->param('hoge') );
のように、受け取ったパラメータを処理せずにテンプレートに渡すと、あっさりと XSS
(クロスサイトスクリプティング) 脆弱性が発生してしまう。
# そんなことする奴はバカ、というのは実に正しいのだが・・・
これはテンプレート側で、
<TMPL_VAR name="hoge" escape="html">
と、HTMLエスケープをしてやることで防げるのだが、すべての箇所に escape="html" を入れるのも繁雑。ということで、default_escape をオプションとして設定すると、 何も指定しない場合 escape が default_escape になる、という patch を書いてみた。
これで、escape が未指定の場合は default_escape で処理される。
use HTML::Template; my $tmpl =<<END; default : <TMPL_VAR name="hoge"> html : <TMPL_VAR name="hoge" escape="html"> url : <TMPL_VAR name="hoge" escape="URL"> 0 : <TMPL_VAR name="hoge" escape=0> "0" : <TMPL_VAR name="hoge" escape="0"> '0' : <TMPL_VAR name="hoge" escape='0'> END my $tp = HTML::Template->new( scalarref => \$tmpl, default_escape => 'html', ); $tp->param( hoge => '<hoge fuga="aaa">' ); print $tp->output;
実行結果
default : <hoge fuga="aaa"> html : <hoge fuga="aaa"> url : %3Choge%20fuga%3D%22aaa%22%3E 0 : <hoge fuga="aaa"> "0" : <hoge fuga="aaa"> '0' : <hoge fuga="aaa">
default_escape を指定して、かつ escape したくない場合は明示的に escape="0" とすれば、そのまま出力される。
...
さてさて、これを本家 HTML::Template に反映させてもらうには、英語でメールを書いて patch を送らなくては。 とりあえず sourceforge.net にアカウントを作って、HTML::Template の ML には参加。ちょっと様子見。