Haml の Filter に #{} で値を渡す場合は XSS に注意

Haml は便利ですねー。 正直最初は なんじゃこりゃ? って思ってたんですが、一度慣れちゃうと二度と素の HTML を書く気が起きないレベルで気に入りました。
今回は Rails の勉強がてら Haml を使っていて、うっかり XSS できちゃう穴が空いてたのでそのまとめです。

使ってる gem のバージョン

Rails 3.2.8
Haml 3.1.7

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 オプションを無視するんでしょうね?
デフォルトは有効で、オプションを指定したら無視の方がいい気がするんですけども・・・
デフォルトで無視しないと困るような状況が何かあるんだろうか。。。