👋

Railsでのエスケープ処理

2025/03/04に公開

Daily Blogging73日目

erbでエスケープを一時的に無効化したくなった
※やらないに越したことはない

erbはデフォでエスケープ

Rails3からerbではデフォルトでエスケープ処理が実行されるようになりました。
https://railsguides.jp/v7.0/3_0_release_notes.html#その他の変更

その前まではhメソッド呼び出して明示的にエスケープしてたと思いますが、その必要はもう無いようです

逆に無効化したい時は明示的にエスケープを無効化する必要が出てきたよ

無効化メソッド

エスケープを無効化するメソッドは3つある

  • html_safe
  • sanitize
  • raw

ざっくりとした違いこんな感じ

メソッド エスケープ XSS のリスク 適用タイミング
raw, <%== %> 無効(そのまま出力) 高(推奨されない) 基本使わない
html_safe 無効(そのまま出力) 高(開発者が責任を持つ) 信頼できる HTML のみ
sanitize 危険なタグを削除 低(安全) ユーザー入力を一部 HTML 許可して表示

rawとhtml_safe

どちらもエスケープを完全無効化するものですが、微妙に挙動が違う。

  • raw
    • 渡された文字列のエスケープをその場限りで無効化する。
  • html_safe
    • 文字列に対して安全フラグをつける

html_safeの方は、フラグをつけて安全か判断するので、一度エスケープしたらずっとエスケープできる。
基本的には使用しないことが望ましく、使う場合は確実に安全だと判断できる時だけにしておく。
ちなみに公式はhtml_safeじゃなくて、sanitizeを推奨している

sanitize

危険性のあるタグだけを取り除いてくれる便利なやつ
これが

<%= sanitize "<b>Bold</b> <script>alert('XSS')</script>" %>

こうなる

<b>Bold</b>

また、許可するタグは指定できるよ

sanitize("<div>Allowed</div><script>Not allowed</script>", tags: %w(div))

Discussion