Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
104
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@satoken0417

[Rails]ERBのエスケープを自在に扱おうぜ

コメントにてご指摘をいただきました

HTMLタグを動的に生成する必要がある場合も、content_tagや(aタグでは)link_toなど、Railsの用意しているヘルパーを使えば、HTMLとして出力するかエスケープするかを適宜判断してくれます(自分でhやhtml_safeしなくて問題ありません)。

using_helper.rb
def return_url2(text)
  link_to text, 'http://google.com/'
end

純粋な文字列リテラルを.html_safeするのはありかもしれませんが、どこから来るかわからない入力で、テキストからHTMLを生成するのは、(ユーザーからHTMLを受け付けることが本当に必要な場合など)よほどの場合をのぞいて避けるべきでしょう。

Rails3からはHTMLタグが自動エスケープする

Rails3からの機能らしいんですが、
ERBで

<%= @text %>

とかやって@text内の文字列をHTMLに変換するときにHTMLタグ等を自動でエスケープするようになってます。

これはユーザーに任意で文字列を入力してもらうときのセキュリティ対策として必須です。

けどHTMLタグをHelperとかで作成したい場合とか困ります。

application_helper.rb
def return_url
  return "<a href="http://google.com">http://google.com</a>"
end
test.html.erb
<%= return_url %>

↓こうHTML出力される

<a href="http://google.com">http://google.com</a>

html_safeメソッドを使おう

そんなときは html_safeメソッドを使う

<%= return_url.html_safe %>

とすると、http://google.com がこちらで意図したとおりaタグで出力されます。

けどセキュリティ的に心配

さっきのHelperメソッドレベルであればhtml_safeメソッドを使うだけで問題ないんですが、ユーザーが任意で入力できるテキストにこちらが意図してHTMLタグを埋め込みたい場合に困ります。

例えばメッセージ等の中にURLが組み込まれている場合、それをaタグで囲ってブラウザ上でクリックできる状態(=有効化)にしたい。。
けどメッセージはユーザーが任意で入力できるため、ユーザーが入力したHTMLタグ等はエスケープ(=無効化)したい。。

という割とよくある?ケースにはこうしたほうが良いです。

test.html.erb
<%= return_url2(h(@test_text)).html_safe %>

ちょっとわかりづらいので順を追って。。

1.controllerから取得したテキストをhメソッドでエスケープ(無効化)します。

test.html.erb
h(@test_text)

2.エスケープした後の@test_textをHelperメソッドのreturn_url2に渡します。
return_url2メソッドは任意)

test.html.erb
return_url2(h(@test_text))

3.return_url2メソッドの結果をhtml_safeにする
(こちらが意図して付けたHTMLタグは有効化する)

test.html.erb
return_url2(h(@test_text)).html_safe

4.完成。

test.html.erb
<%= return_url2(h(@test_text)).html_safe %>

まとめ

html_safeメソッド(HTMLタグの有効化)とhメソッド(HTMLタグのエスケープ=無効化)をきちんと使い分ければHTMLタグエスケープもあなたのもの!

※もうちょっといい書き方あるよってひとは是非教えて下さい!!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
104
Help us understand the problem. What are the problem?