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?


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

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

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

25

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


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>')

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>


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

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.