Jak zakodować ciąg HTML / zmienić jego znaczenie? Czy jest wbudowany?

98

Mam niezaufany ciąg, który chcę pokazać jako tekst na stronie HTML. Muszę usunąć znaki „ <” i „ &” jako jednostki HTML. Im mniej zamieszania, tym lepiej.

Używam UTF8 i nie potrzebuję innych jednostek dla liter akcentowanych.

Czy jest wbudowana funkcja w Rubim lub Railsach, czy powinienem włączyć własną?

kch
źródło
2
Zgodnie z OWASP , dla właściwej ochrony XSS w treści elementu HTML powinno zostać &<>"'/
pominięte

Odpowiedzi:

94

Metoda hpomocnicza:

<%=h "<p> will be preserved" %>
Trevor Bramble
źródło
Cóż, także ucieka>, co jest niepotrzebne, ale wystarczy.
kch
Możesz użyć nawiasów, aby wydrukować niektóre z h, a niektóre bez. <% = h ("<p") + ">"%>
Trevor Bramble
To byłoby głupie. Nie obchodzi mnie, czy ucieknie, czy nie. Po prostu zauważam, że nie jest to wymagane zgodnie ze specyfikacjami HTML.
kch
12
Jest to czasami wymagane w XHTML ze względu na dość irytujące naleganie w specyfikacji XML, aby „]]>” nie zawierało tekstu (zobacz produkcję „CharData”). To sprawia, że ​​zawsze łatwiej (i nieszkodliwie) jest od tego uciec.
bobince
19
dla zainteresowanych hjest alias dlahtml_escape
lightswitch05
141

Sprawdź klasę Ruby CGI . Istnieją metody kodowania i dekodowania HTML, a także adresów URL.

CGI::escapeHTML('Usage: foo "bar" <baz>')
# => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
Christophera Bradforda
źródło
12
Dzięki, to świetnie, bo można to zrobić z poziomu kontrolerów. Nie żebym to zrobił, oczywiście.
Dan Rosenstark
2
Jest to przydatne w testach funkcjonalnych / integracyjnych, do sprawdzania poprawności treści wstawionej do szablonu (gdy treść ma być ze ucieczką HTML).
Alex D
Jeśli treść jest wyświetlana na stronie klienta, innej niż Twoja (gdzie nie możesz kontrolować widoku), jaki jest problem z ucieczką z html przed wstawieniem do bazy danych? Czy jest inna praca?
n00b
Dobrze - ucieczka przed wejściem do bazy danych jest świetna. Po prostu chcesz się upewnić, że nie masz tam żadnych starych hacków, które nie uciekły przed dodaniem go ...
Kevin
5
Bardziej podoba mi się jego synonim: CGI.escape_html
Trantor Liu
77

W Ruby on Rails 3 kod HTML zostanie domyślnie usunięty.

W przypadku ciągów bez ucieczki użyj:

<%= raw "<p>hello world!</p>" %>
RSK
źródło
25

ERB :: Util.html_escape może być używany wszędzie. Jest dostępny bez użycia requirew Railsach.

Viktor Trón
źródło
to faktycznie używa CGI.escapeHTMLpod spodem
akostadinov
@akostadinov - wynik jest jednak inny. Na przykład ERB :: Util.html_escape zamieni apostrofy w & # x27; podczas gdy CGI :: escapeHTML nie
Louis Sayers
@LouisSayers, nie rozumiem, jak to się może stać: `` [43] pry (main)> show-source ERB :: Util.html_escape From: /usr/share/ruby/erb.rb @ line 945: Owner : # <Klasa: ERB :: Util> Widoczność: public Liczba wierszy: 3 def html_escape (s) CGI.escapeHTML (s.to_s) end ``
akostadinov
@akostadinov - hmm ... Po prostu uruchomiłem ponownie i tak, wyprodukowali ten sam wynik. Przysięgam, że dało to różne wyniki, gdy uruchomiłem to w pracy (być może inne zachowanie wersji erb / cgi?). Muszę zobaczyć, dlaczego jutro mam inny wynik w pracy.
Louis Sayers,
17

Jako dodatek do odpowiedzi Christophera Bradforda, aby używać znaków ucieczki HTML w dowolnym miejscu, ponieważ większość ludzi nie używa CGIobecnie, możesz również użyć Rack:

require 'rack/utils'
Rack::Utils.escape_html('Usage: foo "bar" <baz>')
J L
źródło
Czy istnieje lepszy sposób na uniknięcie ciągów znaków w podobny sposób w metodach instancji modelu?
Kodowanie aktywne
15

Możesz użyć albo h()albo html_escape(), ale większość ludzi używa h()konwencji. h()to skrót od html_escape()in rails.

W kontrolerze:

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

Twoim zdaniem:

<%=h @stuff %>

Jeśli przeglądasz źródło HTML: zobaczysz wynik bez faktycznego pogrubienia danych. To znaczy jest zakodowany jako &lt;b&gt;Hello World!&lt;/b&gt;.

Pojawi się i zostanie wyświetlony jako <b>Hello World!</b>

Brian R. Bondy
źródło
9

Porównanie różnych metod:

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

Napisałem własny, aby był kompatybilny z ucieczką Rails ActiveMailer:

def escape_html(str)
  CGI.escapeHTML(str).gsub("&#39;", "'")
end
dorycki
źródło
0

h() przydaje się również do zmiany cudzysłowów.

Na przykład mam widok, który generuje łącze za pomocą pola tekstowego result[r].thtitle. Tekst może zawierać pojedyncze cudzysłowy. Gdybym nie uciekł result[r].thtitlew metodzie potwierdzającej, JavaScript się zepsuł:

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

Uwaga: :htmldeklaracja tytułu jest magicznie chroniona przez Railsy.

Noddinoff
źródło