Railsビューの安全性を完全ガイド!sanitize・raw・html_safeの正しい使い分け
生徒
「Railsのビューで表示される文字って、安全のためにエスケープされると聞いたんですが、エスケープって何ですか?」
先生
「エスケープとは、危険な文字をそのまま実行されないように、別の安全な形に変換することです。RailsのビューではWebアプリを守るために自動で行われているんですよ。」
生徒
「じゃあ、sanitizeやrawやhtml_safeを使うときは、何がどう違うんですか?名前だけ見るとよく分からなくて…」
先生
「それでは、Railsのエスケープの仕組み、そしてsanitize・raw・html_safeの正しい使い分けを順番に解説していきますね。」
1. Railsのエスケープとは?初心者でも理解しやすい仕組み
Webアプリケーションでは、悪意のあるコードが画面に紛れ込むと危険です。例えば入力欄に見えないスクリプトを仕込まれると、画面を開いた人が意図しない動作をさせられる可能性があります。これを防ぐため、Railsではビューに表示するときに「エスケープ」という安全処理を自動で行います。
エスケープとは、HTMLに特別な意味を持つ記号を別の文字に変換することです。例えば、<script>のようなタグが入力された場合、そのまま実行されないように変換して無害化します。初心者の人でも、Railsが自動で守ってくれる仕組みだと覚えておくと理解しやすくなります。
2. sanitizeとは?安全にHTMLを許可したいときに使う方法
sanitizeは、Railsが用意している「安全フィルター」のようなものです。タグが入力されても危険なものを取り除き、安全だと認められたタグだけを残して表示します。例えば太字やリンクなど、ユーザーが見た目を整えたい場合に使うことができます。
<%= sanitize "<b>太字</b>と<script>危険</script>" %>
<b>太字</b>と
このように、太字は残り、危険なscriptタグは削除されます。sanitizeは「安全なHTMLだけを許可したいとき」に使うと覚えると自然です。Railsのビューにおける安全対策としてよく利用される方法です。
3. rawとは?そのままHTMLとして扱う危険な方法
rawは、HTMLのエスケープを行わずにそのまま出力する仕組みです。つまり、入力された内容がそのままHTMLとして画面に反映されます。便利な反面、ユーザーが入力した文字をrawで表示してしまうと、大きなセキュリティリスクが生まれます。
<%= raw "<h1>タイトル</h1>" %>
rawは「信頼できる入れ物だけに使う」というルールが重要です。例えば、プログラムが生成したHTMLや一部の固定データのみです。ユーザーから送られた内容には決して使ってはいけません。Railsのビューは原則として安全性が優先されるため、rawの使用はできるだけ避けることが推奨されています。
4. html_safeとは?文字列に「これは安全」と印をつける仕組み
html_safeは、Railsの文字列オブジェクトに「この文字列はHTMLとして安全なのでエスケープしなくてよい」と印をつける機能です。つまり、rawと似ていて、危険な内容も通してしまう可能性があります。
"<h2>見出し</h2>".html_safe
html_safeもrawと同じく便利ですが、慎重な使い分けが必要です。本当に安全な内容にしか使ってはいけません。Railsではセキュリティを高めるため、必要なとき以外はhtml_safeを避けるべきとされています。
5. sanitize・raw・html_safeの使い分けを理解しよう
Railsではビューの安全性を守ることがとても重要です。sanitizeは安全なタグだけを残せるため最も安全性が高く、rawとhtml_safeは危険な内容が紛れ込む危険があります。特にhtml_safeは見た目では安全に見えても、裏側ではエスケープを無効化してしまうため慎重に扱う必要があります。
ビューのテンプレート(ERB・Haml・Slim)での扱いは同じで、エスケープが自動で行われることを理解した上で使い分けることが大切です。パーシャルに分割している場合も同じで、どのテンプレートでも安全性は統一して考えるべきポイントになります。
6. パーシャルとレイアウトで安全性を保つためのポイント
Railsではビューをパーシャルに分けて管理することがよくありますが、エスケープ処理の仕組みはどのパーシャルでも共通です。例えばコメント欄のテンプレートでユーザーの入力内容を表示する場合、sanitizeを使うことで安全なHTMLだけを許可できます。
<!-- comments/_comment.html.erb -->
<div class="comment-body">
<%= sanitize comment.body %>
</div>
レイアウトやパーシャルでも、ユーザー入力を扱う部分は必ずエスケープを意識します。Railsのビューでは、すべてのパーツが組み合わさって1つの画面になるため、安全性を保つ設計は非常に重要です。
7. 初心者が避けるべき危険な書き方と安全な書き方の例
Railsでは、エスケープの仕組みを理解できていない状態でrawやhtml_safeを使うと、危険なコードがそのまま実行される可能性があります。特に初心者のうちは、便利だからという理由でrawを使う癖をつけないことが大切です。
# 危険な例(ユーザー入力をそのまま表示)
<%= raw @comment.body %>
このような書き方はXSS攻撃の原因になります。
# 安全な例
<%= sanitize @comment.body %>
sanitizeなら安全性が高く、初心者でも安心して使えます。Railsが本来意図している使い方に近いため、ビューのテンプレート設計も自然な形になります。