酒日記

2002 09 17

Tue, 17 Sep 2002

いいちこ (25% × 150 ml)


秋味 (6% × 1000 ml)

相変わらず 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 : &lt;hoge fuga=&quot;aaa&quot;&gt;
html    : &lt;hoge fuga=&quot;aaa&quot;&gt;
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 には参加。ちょっと様子見。


powered by blosxom