LoginSignup
15
9

More than 5 years have passed since last update.

ERBで改行コードをbrタグへ置換する(XSS防止)

Last updated at Posted at 2019-03-15

更新履歴

2019/03/16

記事を投稿しました。

2019/03/17

頂いたコメントをもとに正規表現の書き方を修正しました。

目標

改行コードを含んだ文字列をブラウザ上で改行された状態で表示させる。

hoge.rb
#改行表示させたいターゲットの文字列
@hoge = 'hoge'+"\n" +'hoge'

結論

hoge.rb
hoge = 'hoge'+"\n" +'hoge'
@escaped_hoge = h(hoge).gsub(/\R/, "<br>")
hoge.html.erb
<%= raw(@hoge) %>

結論についての説明

普通に出力した場合(問題あり)

hoge.html.erb
<%= @hoge %>
<!--
hoge hoge
※改行コードがbrタグとして認識されないので改行表示されない
-->

改行コードをbrタグに置換した場合(問題あり)

hoge.rb
@hoge = 'hoge'+"\n" +'hoge'
#正規表現で置換
@hoge.gsub(/\R/, "<br>")
#\Rは複数存在する改行コードを表すメタ文字
hoge.html.erb
<%= @hoge %>
<!--
hoge<br>hoge
※ERBの機能でhtmlエスケープされているので、brタグがタグとして認識されない
-->

エスケープせずに出力した場合(問題あり)

hoge.html.erb
<%= raw(@hoge) %>
<!--
hoge
hoge
※上手くいったように見えるがhtmlエスケープをしていないためセキュアではない
-->
foo.rb
@foo = 'foo'+"\n" +'foo<script>悪意のあるスクリプト</script>'
@foo.gsub(/\R/, "<br>")
foo.html.erb
<%= raw(@foo) %>
<!--
foo
foo
※悪意のあるスクリプトが実行される(XSS脆弱性)
-->

予めエスケープして出力した場合

foo.rb
foo = 'foo'+"\n" +'foo<script>悪意のあるスクリプト</script>'
#hでhtmlエスケープする
@escaped_foo = h(foo)
#htmlエスケープしたあとにbrタグへ置換するので、brタグはエスケープされずに機能する
@escaped_foo.gsub(/\R/, "<br>")
foo.html.erb
<%= raw(@escaped_foo) %>
<!--
foo
foo<script>悪意のあるスクリプト</script>
※scriptタグはhtmlエスケープされているので単なる文字列として解釈される(目標達成)
-->

Railsの場合、置換処理をhelperとして登録しておくと便利

application_helper.erb
module ApplicationHelper
  def nl2br(str)
    h(str).gsub(/\R/, "<br>")
  end
end
hoge.html.erb
<%= raw(nl2br(@hoge)) %>

番外編

simple_formatを使う

hoge.html.erb
<%= simple_format(h(@hoge)) %>
<!--
上記と出力内容は同じだが、出力がpタグで括られる
-->

無駄にpタグを増やすのが嫌なので個人的には使わないです。

15
9
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
9