追記
CPANリリースしました
http://search.cpan.org/dist/JavaScript-Value-Escape/
/追記
malaさんの「HTMLのscriptタグ内に出力されるJavaScriptのエスケープ処理に起因するXSSがとても多い件について」にちょろっとでているgistのコードをモジュールにしました。
JavaScript::Value::Escape - https://github.com/kazeburo/JavaScript-Value-Escape
JavaScript::Value::EscapはHTMLのscriptタグ内にデータを埋め込む際に、少々過剰にエスケープを行うものです。このモジュールではq!”!, q!’!, q!&!, q!>!, q!<!, q!/!, q!\!, qq!\r! と qq!\n! を\u00xxなどに変換します。変換する理由等は上記のエントリによく書かれています。
単独で使う事はあまりなく、テンプレートエンジンと組み合わせて使うことがほとんどだと思います。
use JavaScript::Value::Escape;
use Text::Xslate;
my $tx = Text::Xslate->new(
syntax => 'TTerse',
function => {
js => sub {
javascript_value_escape(@_);
},
}
);
$tx->render_string(<<'EOF',
<html>
<body>
<script>
document.write('[% test | html | js %]');
</script>
<a onclick="alert('[% test | js %]')">alert</a>
</body>
</html>
javascript_value_escapeは、&もエスケープするため、jsフィルタ後にhtmlフィルタを通っても全く問題ありません。rawフィルタを使うなどの例外がなくなります。ただし、malaさんが書いている通り、適用順序を間違えるとXSSが起こりやすいのと、jsフィルタだけで直接document.writeやinnerHTMLに入れ込むとXSSが起こる可能性があります。これを防ぐには、jsフィルタを
javascript_value_escape(Text::Xslate::Util::escape_html(@_));
にしてしまうことが考えられます。あとは、jsの中ではjsフィルタを使う事を確認することになりそうですが、これは機械的にチェックできるかな。
問題なさそうであれば、CPANにあげようと思います。