文字列をHTMLエンコード/エスケープする方法は?組み込みはありますか?


98

HTMLページにテキストとして表示したい信頼できない文字列があります。文字 ' <'および ' &'をHTMLエンティティとしてエスケープする必要があります。騒ぎが少ないほど良いです。

私はUTF8を使用しており、アクセント付き文字に他のエンティティは必要ありません。

RubyやRailsに組み込み関数はありますか、それとも自分で作成する必要がありますか?


2
OWASPによると、次の6つの文字は、HTML要素の内容に適切なXSSの保護のためにエスケープする必要があります:&<>"'/
SFFC

回答:


94

hヘルパーメソッド:

<%=h "<p> will be preserved" %>

まあ、それも>をエスケープしますが、これは不必要ですが、そうします。
kch、2009年

括弧を使用して、hがあるものとないものを印刷できます。<%= h( "<p")+ ">"%>
Trevor Bramble

今ではばかげているでしょう。脱出してもしなくてもかまいません。私はそれがhtml仕様ごとに必要とされていないことに注意しています。
kch、2009年

12
それはだ時折による「]]>」( 'CHARDATAの生産を参照)、テキストのうちに保持されることをXML仕様のかなり迷惑な主張にXHTMLに必要。これにより、常に簡単に(そして無害に)脱出できます。
ボビンス2009年

19
興味hがある人のためのエイリアスですhtml_escape
lightswitch05

141

Ruby CGIクラスをチェックアウトしてください。HTMLおよびURLをエンコードおよびデコードする方法があります。

CGI::escapeHTML('Usage: foo "bar" <baz>')
# => "Usage: foo &quot;bar&quot; &lt;baz&gt;"

12
おかげで、これはコントローラーから実行できるので素晴らしいです。もちろんそうするつもりはありません。
Dan Rosenstark、2011

2
これは、機能/統合テストで、テンプレートに挿入されたコンテンツの正しさをチェックするのに役立ちます(コンテンツがHTMLエスケープされることになっている場合)。
Alex D

コンテンツがクライアントのWebサイトに表示されている場合(データベースを挿入する前にHTMLをエスケープする場合の問題)別の回避策はありますか?
n00b 2013年

正しい-データベースに入る前にエスケープするのは素晴らしいことです。あなたはそれを追加する前からそこに古いエスケープされていないハッキングがないことを確認したいだけです...
Kevin

5
私はその同義語がもっと好きです:CGI.escape_html
Trantor Liu

77

Ruby on Rails 3では、HTMLはデフォルトでエスケープされます。

エスケープされていない文字列の場合は、次を使用します。

<%= raw "<p>hello world!</p>" %>

25

ERB :: Util.html_escapeはどこでも使用できます。requireRailsで使わなくても利用できます。


これは実際にはCGI.escapeHTML下で使用されています
akostadinov

@akostadinov-結果は異なります。たとえば、ERB :: Util.html_escapeはアポストロフィを&#x27;に変換します。一方、CGI :: escapeHTMLはそうしません
Louis Sayers、

@LouisSayers、どうしてこうなるのかわかりません: `` `[43] pry(main)> show-source ERB :: Util.html_escape From:/usr/share/ruby/erb.rb @ line 945:Owner :#<Class:ERB :: Util>可視性:public行数:3 def html_escape(s)CGI.escapeHTML(s.to_s)end `` `
akostadinov

@akostadinov-うーん...もう一度実行すると、同じ出力が生成されました。私がこれを仕事で実行したときに異なる結果が生成されたことを私は誓います(おそらく異なるerb / cgiバージョンの動作?)。明日仕事で別の結果になった理由を確認する必要があります。
Louis Sayers、2015

17

HTMLエスケープをどこでも使用するというクリストファーブラッドフォードの回答に加えて、CGI現在ほとんどの人は使用していないため、以下も使用できますRack

require 'rack/utils'
Rack::Utils.escape_html('Usage: foo "bar" <baz>')

モデルインスタンスメソッドで同様の方法で文字列をエスケープするより良い方法はありますか?
アクティブなコーディング

15

h()またはのいずれかを使用できますhtml_escape()が、ほとんどの人はh()慣例に従って使用します。 in railsのh()略ですhtml_escape()

コントローラで:

@stuff = "<b>Hello World!</b>"

あなたの見解では:

<%=h @stuff %>

HTMLソースを表示する場合:実際にデータを太字にしなくても出力が表示されます。つまり、としてエンコードされ&lt;b&gt;Hello World!&lt;/b&gt;ます。

次のように表示されます <b>Hello World!</b>


9

さまざまな方法の比較:

> CGI::escapeHTML("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

> Rack::Utils.escape_html("quote ' double quotes \"")
=> "quote &#x27; double quotes &quot;"

> ERB::Util.html_escape("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

Rails ActiveMailerのエスケープと互換性があるように自分で作成しました。

def escape_html(str)
  CGI.escapeHTML(str).gsub("&#39;", "'")
end

0

h() 引用符をエスケープするのにも役立ちます。

たとえば、テキストフィールドを使用してリンクを生成するビューがありますresult[r].thtitle。テキストには単一引用符を含めることができます。result[r].thtitleconfirmメソッドでエスケープしなかった場合、JavaScriptは壊れます。

&lt;%= link_to_remote "#{result[r].thtitle}", :url=>{ :controller=>:resource,
:action         =>:delete_resourced,
:id     => result[r].id,
:th     => thread,                                                                                                      
:html       =>{:title=> "<= Remove"},                                                       
:confirm    => h("#{result[r].thtitle} will be removed"),                                                   
:method     => :delete %>

&lt;a href="#" onclick="if (confirm('docs: add column &amp;apos;dummy&amp;apos; will be removed')) { new Ajax.Request('/resource/delete_resourced/837?owner=386&amp;th=511', {asynchronous:true, evalScripts:true, method:'delete', parameters:'authenticity_token=' + encodeURIComponent('ou812')}); }; return false;" title="&lt;= Remove">docs: add column 'dummy'</a>

注::htmlタイトル宣言はRailsによって魔法のようにエスケープされます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.