raw vs. html_safe vs. h, um html zu entkommen

323

Angenommen, ich habe die folgende Zeichenfolge

@x = "<a href='#'>Turn me into a link</a>"

Meiner Ansicht nach soll ein Link angezeigt werden. Das heißt, ich möchte nicht, dass alles in @x entkoppelt und als Zeichenfolge angezeigt wird. Was ist der Unterschied zwischen der Verwendung

<%= raw @x %>
<%= h @x %>
<%= @x.html_safe %>

?

grautur
quelle
Da niemand es erwähnte, dachte ich, ich würde auch erwähnen, dass <%== @x %>es einen Alias ​​für <%= raw(@x) %> edgeguides.rubyonrails.org/…
CTS_AE

Antworten:

386

Betrachtung der Schienen 3:

html_safe"setzt den String" als HTML-sicher (es ist etwas komplizierter, aber im Grunde ist es das). Auf diese Weise können Sie nach Belieben HTML-sichere Zeichenfolgen von Helfern oder Modellen zurückgeben.

hkann nur innerhalb eines Controllers oder einer Ansicht verwendet werden, da es von einem Helfer stammt. Dadurch wird erzwungen, dass die Ausgabe maskiert wird. Es ist nicht wirklich veraltet, aber Sie werden es höchstwahrscheinlich nicht mehr verwenden: Die einzige Verwendung besteht darin, eine html_safeDeklaration "zurückzusetzen" , was ziemlich ungewöhnlich ist.

Das Voranstellen Ihres Ausdrucks mit rawist eigentlich gleichbedeutend mit dem Aufruf von to_sverkettet mit html_safe, wird jedoch wie bei einem Helfer deklariert h, sodass er nur für Controller und Ansichten verwendet werden kann.

" SafeBuffers and Rails 3.0 " ist eine nette Erklärung, wie das SafeBuffers (die Klasse, die die html_safeMagie macht) funktioniert.

Fábio Batista
quelle
42
Ich würde nicht sagen, dass hdas jemals veraltet sein wird. Die Verwendung "Hi<br/>#{h@ user.name}".html_safeist weit verbreitet und wird akzeptiert.
Maletor
1
@ Maletor interessante Verwendung, obwohl ich immer noch denke, dass es in die "ungewöhnliche" Kategorie fällt.
Fábio Batista
5
Die Zeichenfolge # html_safe gibt tatsächlich eine Instanz von ActiveSupport :: SafeBuffer zurück, die die ursprüngliche Zeichenfolge umschließt und #html_safe ist. . Die ursprüngliche Zeichenfolge wird nicht zu #html_safe? nach dem Aufruf von #html_safe darauf.
jmaxyz
9
Beachten Sie, dass es einen subtilen Unterschied zwischen rawund html_safein der Praxis gibt: raw(nil)Gibt eine leere Zeichenfolge zurück, während nil.html_safeeine Ausnahme ausgelöst wird.
Van der Hoorn
2
hwird eine html_safe-Deklaration nicht "zurücksetzen". Wenn eine Zeichenfolge ist html_safe, hwird nichts tun.
GuiGS
113

Ich denke , es trägt zu wiederholen: html_safenicht nicht HTML-entkommen Zeichenfolge. Tatsächlich wird verhindert, dass Ihre Zeichenfolge maskiert wird.

<%= "<script>alert('Hello!')</script>" %>

wird setzen:

&lt;script&gt;alert(&#x27;Hello!&#x27;)&lt;/script&gt;

in Ihre HTML-Quelle (yay, so sicher!), während:

<%= "<script>alert('Hello!')</script>".html_safe %>

öffnet den Alarmdialog (sind Sie sicher, dass Sie das möchten?). Sie möchten also wahrscheinlich html_safekeine vom Benutzer eingegebenen Zeichenfolgen aufrufen .

Roasm
quelle
81
Mit anderen Worten, html_safe ist nicht "Bitte machen Sie dieses HTML sicher", es ist das Gegenteil - Sie als Programmierer sagen Rails, dass "diese Zeichenfolge HTML-sicher ist, versprochen!"
Paul MurrayCbr
eigentlich bin ich hier , um herauszufinden , ob es tatsächlich tut unescape oder ob es nur eine Marke macht , dass es nicht notwendig ist to_escape . Ein ziemlicher Unterschied. Na ja, dann geht es los, um den Quellcode zu lesen.
Simon B.
Das Konzept von "html_safe" ist nur ein Meta-Flag in der Zeichenfolge. Etwas markieren, html_safedas weder entkommt noch entkommt. Das Endergebnis, wenn etwas als nicht HTML-sicher markiert und dann das implizite Escapezeichen des ERB <% = -Tags verwendet wird, entspricht möglicherweise dem Entschlüsseln von Daten und dem erneuten Escapezeichen bei der Ausgabe. Funktionell funktioniert dies jedoch nicht. Ein bisschen wie der Unterschied von (6 * -1 * -1) gegen 6.
Ben Zittlau
46

Der Unterschied liegt zwischen Rails html_safe()und raw(). Es gibt einen ausgezeichneten Beitrag von Yehuda Katz dazu, und es läuft wirklich darauf hinaus:

def raw(stringish)

  stringish.to_s.html_safe

end

Ja, es raw()handelt sich um einen Wrapper html_safe(), der die Eingabe in String erzwingt und dann aufruft html_safe(). Es ist auch der Fall, dass raw()es sich um einen Helfer in einem Modul handelt, während html_safe()es sich um eine Methode für die String-Klasse handelt, mit der eine neue ActiveSupport :: SafeBuffer-Instanz erstellt wird@dirty Flag enthält.

Siehe " Rails 'html_safe vs. raw ".

Pankhuri
quelle
30
  1. html_safe ::

    Markiert eine Zeichenfolge als vertrauenswürdig. Es wird in HTML eingefügt, ohne dass ein zusätzliches Escapezeichen ausgeführt wird.

    "<a>Hello</a>".html_safe
    #=> "<a>Hello</a>"
    
    nil.html_safe
    #=> NoMethodError: undefined method `html_safe' for nil:NilClass
  2. raw ::

    rawist nur eine Hülle herum html_safe. Verwenden Sie rawdiese Option, wenn die Wahrscheinlichkeit besteht, dass die Zeichenfolge angezeigt wird nil.

    raw("<a>Hello</a>")
    #=> "<a>Hello</a>"
    
    raw(nil)
    #=> ""
  3. h Alias ​​für html_escape :

    Eine Dienstprogrammmethode zum Escapezeichen von HTML-Tag-Zeichen. Verwenden Sie diese Methode, um unsichere Inhalte zu umgehen.

    In Rails 3 und höher wird es standardmäßig verwendet, sodass Sie diese Methode nicht explizit verwenden müssen

Deepak Mahakale
quelle
14

Der beste sichere Weg ist: <%= sanitize @x %>

Es wird XSS vermeiden!

Guilherme Y. Hatano
quelle
2

In Simple Rails-Begriffen:

h Entfernen Sie HTML-Tags in Zahlenzeichen, damit das Rendern Ihr HTML nicht beschädigt

html_safe Setzt einen Booleschen Wert in der Zeichenfolge, sodass die Zeichenfolge als HTML-Speicher betrachtet wird

raw Es konvertiert in html_safe in string

user3118220
quelle
hist html_safe, was bedeutet, dass der HTML-Code so wie er ist gerendert wird.
Dave Newton
Die Antwort ist richtig: h ist html_escape ... von der Rails-Codebasis
notapatch