Haml の Filter に #{} で値を渡す場合は XSS に注意
Haml は便利ですねー。
正直最初は なんじゃこりゃ? って思ってたんですが、一度慣れちゃうと二度と素の HTML を書く気が起きないレベルで気に入りました。
今回は Rails の勉強がてら Haml を使っていて、うっかり XSS できちゃう穴が空いてたのでそのまとめです。
使ってる gem のバージョン
XSS が行えるパターン
Haml の Filter に #{@entry.body} といった形で値を渡している場合。
(※ @entry.body が既にサニタイズされていれば問題ありません)
僕は @entry.body がサニタイズされていない状況で、以下の形でやらかしてました。
:markdown
#{@entry.body}
Haml で普通に #{} する分にはサニタイズされていたので、すっかり油断してました。
XSS が行える原因
Haml のドキュメントにまんま書いてありました o...rz
Currently, filters ignore the :escape_html option. This means that #{} interpolation within filters is never HTML-escaped.
参考:http://haml.info/docs/yardoc/file.REFERENCE.html#filters
解決策
Haml の Filter に #{} で値を渡す場合は h メソッド経由にする。
:markdown
#{h @entry.body}
これでXSSは行えなくなります。
なんとなく残った疑問
というか、なんで Filter は :espace_html オプションを無視するんでしょうね?
デフォルトは有効で、オプションを指定したら無視の方がいい気がするんですけども・・・
デフォルトで無視しないと困るような状況が何かあるんだろうか。。。