Làm thế nào để mã hóa HTML / thoát một chuỗi? Có tích hợp sẵn không?


98

Tôi có một chuỗi không đáng tin cậy mà tôi muốn hiển thị dưới dạng văn bản trong trang HTML. Tôi cần thoát khỏi các ký tự ' <' và ' &' dưới dạng các thực thể HTML. Càng ít phiền phức càng tốt.

Tôi đang sử dụng UTF8 và không cần các thực thể khác cho các chữ cái có dấu.

Có một hàm tích hợp sẵn trong Ruby hoặc Rails không, hay tôi nên tự cuộn?


2
Theo OWASP , sáu ký tự sau nên được thoát để bảo vệ XSS thích hợp trong nội dung phần tử HTML:&<>"'/
sffc

Câu trả lời:


94

Các hphương pháp helper:

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

Chà, nó cũng thoát>, điều này là không cần thiết, nhưng nó sẽ làm được.
kch

Bạn có thể sử dụng dấu ngoặc đơn để in một số có h và một số không có. <% = h ("<p") + ">"%>
Trevor Bramble

Bây giờ điều đó sẽ thật ngớ ngẩn. Tôi không quan tâm lắm đến việc nó có thoát được hay không. Tôi chỉ lưu ý rằng nó không bắt buộc theo thông số kỹ thuật html.
kch

12
thỉnh thoảng yêu cầu trong XHTML do khăng khăng khá khó chịu spec XML rằng ']]>' được giữ ra khỏi văn bản (xem 'CharData' sản xuất). Điều này làm cho nó thường dễ dàng hơn (và vô hại) để luôn luôn thoát khỏi nó.
bobince

19
cho những người quan tâm hlà một bí danh chohtml_escape
lightswitch.

141

Kiểm tra lớp Ruby CGI . Có các phương pháp để mã hóa và giải mã HTML cũng như URL.

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

12
Cảm ơn, điều này thật tuyệt vì nó có thể được thực hiện từ bộ điều khiển. Tất nhiên là không phải tôi sẽ làm điều đó.
Dan Rosenstark

2
Điều này rất hữu ích trong các bài kiểm tra chức năng / tích hợp, để kiểm tra tính đúng đắn của nội dung được chèn vào mẫu (khi nội dung được cho là thoát HTML).
Alex D

Nếu nội dung đang được hiển thị trong trang web của khách hàng, không phải của riêng bạn (nơi bạn không thể kiểm soát chế độ xem), thì có vấn đề gì với việc thoát html trước khi chèn vào cơ sở dữ liệu không? Có một công việc khác xung quanh?
n00b

Phải - thoát trước khi nhập vào cơ sở dữ liệu là rất tốt. Bạn chỉ muốn đảm bảo rằng bạn không có bất kỳ bản hack cũ nào chưa thoát trong đó từ trước khi bạn thêm nó ...
Kevin

5
Tôi thích từ đồng nghĩa của nó hơn: CGI.escape_html
Trantor Liu

77

Trong Ruby on Rails 3 HTML sẽ được thoát theo mặc định.

Đối với chuỗi không thoát, sử dụng:

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

25

ERB :: Util.html_escape có thể được sử dụng ở mọi nơi. Nó có sẵn mà không cần sử dụng requiretrong Rails.


điều này thực sự đang sử dụng CGI.escapeHTMLbên dưới
akostadinov

@akostadinov - tuy nhiên, kết quả lại khác. Ví dụ: ERB :: Util.html_escape sẽ chuyển dấu nháy đơn thành & # x27; trong khi CGI :: EscapeHTML sẽ không
Louis Sayers

@LouisSayers, tôi không thể thấy điều đó có thể xảy ra như thế nào: `` [43] pry (main)> show-source ERB :: Util.html_escape Từ: /usr/share/ruby/erb.rb @ line 945: Owner : # <class: ERB :: util> Tầm nhìn: public số dòng: 3 def html_escape (s) CGI.escapeHTML (s.to_s) cuối `` `
akostadinov

@akostadinov - hmm ... Chỉ cần chạy lại và vâng, họ đã tạo ra cùng một đầu ra. Tôi thề rằng điều này tạo ra các kết quả khác nhau khi tôi chạy nó tại nơi làm việc (có lẽ hành vi phiên bản erb / cgi khác nhau?). Tôi sẽ phải xem lý do tại sao tôi có một kết quả khác trong công việc vào ngày mai.
Louis Sayers

17

Ngoài câu trả lời của Christopher Bradford để sử dụng HTML thoát ở bất kỳ đâu, vì hầu hết mọi người CGIngày nay không sử dụng , bạn cũng có thể sử dụng Rack:

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

Có cách nào tốt hơn để thoát chuỗi theo cách tương tự trong các phương thức phiên bản mô hình không?
Mã hóa hoạt động

15

Bạn có thể sử dụng một trong hai h()hoặc html_escape(), nhưng hầu hết mọi người sử dụng h()theo quy ước. h()là viết tắt của html_escape()trong đường ray.

Trong bộ điều khiển của bạn:

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

Theo quan điểm của bạn:

<%=h @stuff %>

Nếu bạn xem nguồn HTML: bạn sẽ thấy đầu ra mà không thực sự in đậm dữ liệu. Tức là nó được mã hóa thành&lt;b&gt;Hello World!&lt;/b&gt; .

Nó sẽ xuất hiện được hiển thị dưới dạng <b>Hello World!</b>


9

So sánh các phương pháp khác nhau:

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

Tôi đã viết của riêng mình để tương thích với thoát Rails ActiveMailer:

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

0

h() cũng hữu ích để thoát khỏi dấu ngoặc kép.

Ví dụ: tôi có một dạng xem tạo liên kết bằng trường văn bản result[r].thtitle. Văn bản có thể bao gồm các dấu ngoặc kép. Nếu tôi không thoát result[r].thtitletrong phương thức xác nhận, thì Javascript sẽ bị hỏng:

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

Lưu ý: phần :htmlkhai báo tiêu đề được thoát một cách kỳ diệu bởi Rails.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.