Bagaimana cara menyandikan / melepaskan string HTML? Apakah ada built-in?


98

Saya memiliki string tidak tepercaya yang ingin saya tampilkan sebagai teks di halaman HTML. Saya harus melepaskan karakter ' <' dan ' &' sebagai entitas HTML. Semakin sedikit keributan semakin baik.

Saya menggunakan UTF8 dan tidak memerlukan entitas lain untuk huruf beraksen.

Apakah ada fungsi bawaan di Ruby atau Rails, atau haruskah saya menggulungnya sendiri?


2
Menurut OWASP , enam karakter berikut harus di-escape untuk perlindungan XSS yang tepat dalam konten elemen HTML:&<>"'/
sffc

Jawaban:


94

The hhelper Metode:

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

Yah, itu juga lolos>, yang tidak perlu, tapi itu akan berhasil.
kch

Anda dapat menggunakan tanda kurung untuk mencetak beberapa dengan h dan beberapa tanpa. <% = h ("<p") + ">"%>
Trevor Bramble

Nah, itu konyol. Saya tidak terlalu peduli apakah itu lolos atau tidak. Saya hanya mencatat itu tidak diperlukan sesuai spesifikasi html.
kch

12
Kadang- kadang diperlukan dalam XHTML karena desakan spesifikasi XML yang agak mengganggu bahwa ']]>' dijauhkan dari teks (lihat produksi 'CharData'). Hal ini umumnya membuat lebih mudah (dan tidak berbahaya) untuk selalu menghindarinya.
bobince

19
bagi mereka yang tertarik hadalah alias untukhtml_escape
lightswitch05

141

Lihat kelas Ruby CGI . Ada metode untuk menyandikan dan mendekode HTML serta URL.

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

12
Terima kasih, ini bagus karena dapat dilakukan dari pengontrol. Bukannya aku akan melakukannya, tentu saja.
Dan Rosenstark

2
Ini berguna dalam pengujian fungsional / integrasi, untuk memeriksa kebenaran konten yang dimasukkan ke dalam template (saat konten seharusnya di-escape dengan HTML).
Alex D

Jika konten ditampilkan di situs web klien, selain milik Anda sendiri (di mana Anda tidak dapat mengontrol tampilan), apa masalah dengan keluar dari html sebelum memasukkan ke dalam database? Apakah ada solusi lain?
n00b

Benar - melarikan diri sebelum masuk ke database itu bagus. Anda hanya ingin memastikan bahwa Anda tidak memiliki peretasan lama yang tidak lolos sebelum Anda menambahkannya ...
Kevin

5
Saya lebih suka sinonimnya: CGI.escape_html
Trantor Liu

77

Di Ruby on Rails 3 HTML akan di-escape secara default.

Untuk string non-escape, gunakan:

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

25

ERB :: Util.html_escape dapat digunakan dimana saja. Ini tersedia tanpa menggunakan requiredi Rails.


ini sebenarnya menggunakan di CGI.escapeHTMLbawah
akostadinov

@akostadinov - Namun hasilnya berbeda. Misalnya, ERB :: Util.html_escape akan mengubah apostrof menjadi & # x27; sedangkan CGI :: escapeHTML tidak akan
Louis Sayers

@LouisSayers, saya tidak bisa melihat bagaimana itu bisa terjadi: `` [43] pry (main)> show-source ERB :: Util.html_escape From: /usr/share/ruby/erb.rb @ line 945: Owner : # <Class: ERB :: Util> Visibility: public Jumlah baris: 3 def html_escape (s) CGI.escapeHTML (s.to_s) end ``
akostadinov

@akostadinov - hmm ... Jalankan lagi dan ya, mereka menghasilkan keluaran yang sama. Saya bersumpah ini menghasilkan hasil yang berbeda ketika saya menjalankan ini di tempat kerja (mungkin perilaku versi erb / cgi berbeda?). Saya harus melihat mengapa saya mendapat hasil yang berbeda di tempat kerja besok.
Louis Sayers

17

Selain jawaban Christopher Bradford untuk menggunakan pelolosan HTML di mana pun, karena kebanyakan orang tidak menggunakannya CGIsaat ini, Anda juga dapat menggunakan Rack:

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

Apakah ada cara yang lebih baik untuk melepaskan string dengan cara yang serupa dalam metode contoh model?
Pengkodean aktif

15

Anda dapat menggunakan salah satu h()atau html_escape(), tetapi kebanyakan orang menggunakan h()berdasarkan konvensi. h()adalah kependekan dari html_escape()in rails.

Di pengontrol Anda:

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

Dalam pandangan Anda:

<%=h @stuff %>

Jika Anda melihat sumber HTML: Anda akan melihat output tanpa benar-benar menebalkan datanya. Yaitu itu dikodekan sebagai &lt;b&gt;Hello World!&lt;/b&gt;.

Ini akan muncul dan ditampilkan sebagai <b>Hello World!</b>


9

Perbandingan berbagai metode:

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

Saya menulis milik saya sendiri agar kompatibel dengan pelarian Rails ActiveMailer:

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

0

h() juga berguna untuk menghilangkan tanda kutip.

Misalnya, saya memiliki tampilan yang menghasilkan tautan menggunakan bidang teks result[r].thtitle. Teks dapat menyertakan tanda kutip tunggal. Jika saya tidak melarikan diri result[r].thtitledalam metode konfirmasi, Javascript akan rusak:

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

Catatan: :htmldeklarasi judul secara ajaib di-escape oleh Rails.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.