Scriptタグを含む以下の文字列をいろんな方法で出力して、違いを比較します。
@hoge
<script>
alert('you are an idiot');
</script>
そのまま出力
erb
<%= @hoge %>
出力
<script> alert('you are an idiot'); </script>
結果
XSSは回避できるが、改行やスペースが反映されない
html_safe
erb
<%= @hoge.html_safe %>
出力
Scriptが実行される!
結果
XSSを誘発します。html_safe
はその名前に反して全然safeじゃないです。
simple_format(@hoge
, sanitize: true)
erb
<%= simple_format(@hoge, sanitize: true) %>
出力
alert('you are an idiot');
結果
script
タグが消去される
h(@hoge
)
erb
<%= h(@hoge) %>
出力
<script> alert('you are an idiot'); </script>
結果
XSSは回避できるが、改行やスペースが反映されない
simple_format(h(@hoge
))
erb
<%= simple_format(h(@hoge)) %>
出力
<script>
alert('you are an idiot');
</script>
結果
XSSは発生しない。scriptタグはエスケープされ、改行も保持。改行後のスペースだけが反映されない。
所感
改行を反映させたい時はsimple_format(h(@hoge)
が良さそう。