Wie kann man einen String HTML-codieren / maskieren? Gibt es eine eingebaute?

98

Ich habe eine nicht vertrauenswürdige Zeichenfolge, die ich als Text in einer HTML-Seite anzeigen möchte. Ich muss die Zeichen ' <' und ' &' als HTML-Entitäten maskieren. Je weniger Aufhebens desto besser.

Ich verwende UTF8 und benötige keine anderen Entitäten für Buchstaben mit Akzent.

Gibt es eine integrierte Funktion in Ruby oder Rails oder sollte ich meine eigene rollen?

kch
quelle
2
Laut OWASP sollten die folgenden sechs Zeichen für einen ordnungsgemäßen XSS-Schutz im Inhalt von HTML-Elementen &<>"'/
maskiert

Antworten:

94

Die hHilfsmethode:

<%=h "<p> will be preserved" %>
Trevor Bramble
quelle
Nun, es entkommt auch>, was unnötig ist, aber es wird reichen.
Kch
Sie können Klammern verwenden, um einige mit h und einige ohne zu drucken. <% = h ("<p") + ">"%>
Trevor Bramble
Das wäre dumm. Es ist mir egal, ob es entkommen ist oder nicht. Ich stelle nur fest, dass es gemäß den HTML-Spezifikationen nicht erforderlich ist.
Kch
12
In XHTML ist dies gelegentlich erforderlich, da die XML-Spezifikation ziemlich nervig darauf besteht, dass ']]>' nicht in Textform enthalten ist (siehe 'CharData'-Produktion). Dies macht es im Allgemeinen einfacher (und harmloser), immer zu entkommen.
Bobince
19
Für Interessierte hist ein Alias ​​fürhtml_escape
Lichtschalter05
141

Testen Sie die Ruby CGI- Klasse. Es gibt Methoden zum Codieren und Decodieren von HTML sowie URLs.

CGI::escapeHTML('Usage: foo "bar" <baz>')
# => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
Christopher Bradford
quelle
12
Danke, das ist großartig, da es von den Controllern aus gemacht werden kann. Natürlich nicht, dass ich das tun würde.
Dan Rosenstark
2
Dies ist nützlich bei Funktions- / Integrationstests, um die Richtigkeit des in eine Vorlage eingefügten Inhalts zu überprüfen (wenn der Inhalt HTML-maskiert sein soll).
Alex D
Wenn der Inhalt auf einer anderen Client-Website als Ihrer eigenen angezeigt wird (wo Sie die Ansicht nicht steuern können), was ist das Problem, wenn Sie den HTML-Code vor dem Einfügen in die Datenbank verlassen? Gibt es noch eine andere Lösung?
n00b
Es ist großartig, vor dem Eintritt in die Datenbank zu entkommen. Sie wollen nur sicherstellen, dass Sie keine alten, nicht entkommenen Hacks haben, bevor Sie sie hinzugefügt haben ...
Kevin
5
Ich mag sein Synonym mehr: CGI.escape_html
Trantor Liu
77

In Ruby on Rails 3 wird HTML standardmäßig maskiert.

Verwenden Sie für nicht maskierte Zeichenfolgen:

<%= raw "<p>hello world!</p>" %>
RSK
quelle
25

ERB :: Util.html_escape kann überall verwendet werden. Es ist ohne Verwendung requirein Rails verfügbar .

Viktor Trón
quelle
Dies ist tatsächlich CGI.escapeHTMLunter
Akostadinov
@akostadinov - das Ergebnis ist jedoch anders. Beispielsweise verwandelt ERB :: Util.html_escape Apostrophe in & # x27; während CGI :: EscapeHTML nicht
Louis Sayers
@ LouisSayers, ich kann nicht sehen, wie das passieren kann: `` `[43] pry (main)> show-source ERB :: Util.html_escape Von: /usr/share/ruby/erb.rb @ line 945: Owner : # <Klasse: ERB :: Util> Sichtbarkeit: public Anzahl der Zeilen: 3 def html_escape (s) CGI.escapeHTML (s.to_s) end `` `
akostadinov
@akostadinov - hmm ... Bin gerade wieder gelaufen und ja, sie haben die gleiche Ausgabe produziert. Ich schwöre, dass dies zu unterschiedlichen Ergebnissen führte, als ich dies bei der Arbeit ausführte (möglicherweise ein anderes Verhalten der erb / cgi-Version?). Ich muss sehen, warum ich morgen bei der Arbeit ein anderes Ergebnis erzielt habe.
Louis Sayers
17

Eine Ergänzung zu Christopher Bradfords Antwort, den HTML-Code überall zu verwenden, da die meisten Leute ihn CGIheutzutage nicht verwenden , können Sie auch Folgendes verwenden Rack:

require 'rack/utils'
Rack::Utils.escape_html('Usage: foo "bar" <baz>')
J L
quelle
Gibt es eine bessere Möglichkeit, Zeichenfolgen in Modellinstanzmethoden auf ähnliche Weise zu umgehen?
Codierung aktiv
15

Sie können entweder h()oder verwenden html_escape(), aber die meisten Leute verwenden es h()gemäß Konvention. h()ist die Abkürzung für html_escape()in Rails.

In Ihrem Controller:

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

Aus Ihrer Sicht:

<%=h @stuff %>

Wenn Sie die HTML-Quelle anzeigen: Sie sehen die Ausgabe, ohne die Daten tatsächlich zu fetten. Dh es ist verschlüsselt als &lt;b&gt;Hello World!&lt;/b&gt;.

Es wird angezeigt und angezeigt als <b>Hello World!</b>

Brian R. Bondy
quelle
9

Vergleich der verschiedenen Methoden:

> 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;"

Ich habe meine eigene geschrieben, um mit Rails ActiveMailer kompatibel zu sein.

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

h() ist auch nützlich, um Anführungszeichen zu umgehen.

Zum Beispiel habe ich eine Ansicht, die einen Link mithilfe eines Textfelds generiert result[r].thtitle. Der Text kann einfache Anführungszeichen enthalten. Wenn ich nicht result[r].thtitlein der Bestätigungsmethode entkommen würde, würde das Javascript brechen:

&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>

Hinweis: Die :htmlTiteldeklaration wird von Rails auf magische Weise maskiert.

Noddinoff
quelle