วิธีเข้ารหัส HTML / หลีกเลี่ยงสตริง มีในตัวหรือไม่?


99

ฉันมีสตริงที่ไม่น่าเชื่อถือซึ่งฉันต้องการแสดงเป็นข้อความในหน้า HTML ฉันต้องการหลีกเลี่ยงตัวอักษร ' <' และ ' &' เป็นเอนทิตี HTML เอะอะน้อยยิ่งดี

ฉันใช้ UTF8 และไม่ต้องการเอนทิตีอื่นสำหรับตัวอักษรเน้นเสียง

ใน Ruby หรือ Rails มีฟังก์ชันในตัวหรือไม่หรือควรม้วนเอง


2
ตาม OWASPควรใช้อักขระหกตัวต่อไปนี้เพื่อป้องกัน XSS ที่เหมาะสมในเนื้อหาองค์ประกอบ HTML:&<>"'/
sffc

คำตอบ:


96

hวิธีการช่วยเหลือ:

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

มันยังหนี> ซึ่งไม่จำเป็น แต่มันจะทำ
kch

คุณสามารถใช้วงเล็บเพื่อพิมพ์บางส่วนโดยมี h และบางส่วนไม่มี <% = h ("<p") + ">"%>
Trevor Bramble

ตอนนี้จะโง่ ฉันไม่สนใจมากว่ามันจะหนีไปหรือไม่ ฉันแค่สังเกตว่ามันไม่จำเป็นสำหรับข้อกำหนด html
kch

12
มันเป็นบางครั้งจำเป็นต้องใช้ใน XHTML เนื่องจากการเรียกร้องที่น่ารำคาญมากกว่าข้อมูลจำเพาะของ XML ที่ ']]>' ถูกกันออกจากข้อความ (ดูการผลิต 'CharData') สิ่งนี้ทำให้โดยทั่วไปง่ายขึ้น (และไม่เป็นอันตราย) ในการหลบหนี
bobince

20
สำหรับผู้ที่สนใจhเป็นนามแฝงของhtml_escape
lightswitch05

141

ชำระเงินคลาสRuby CGI มีวิธีการเข้ารหัสและถอดรหัส HTML เช่นเดียวกับ URL

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

12
ขอบคุณนี่เป็นสิ่งที่ยอดเยี่ยมเนื่องจากสามารถทำได้จากตัวควบคุม ไม่ใช่ว่าฉันจะทำอย่างนั้นแน่นอน
Dan Rosenstark

2
สิ่งนี้มีประโยชน์ในการทดสอบการทำงาน / การผสานรวมสำหรับการตรวจสอบความถูกต้องของเนื้อหาที่แทรกลงในเทมเพลต (เมื่อเนื้อหาควรเป็น HTML-Escape)
Alex D

หากเนื้อหาถูกแสดงในเว็บไซต์ไคลเอนต์อื่น ๆ ของคุณเอง (ซึ่งคุณไม่สามารถควบคุมมุมมองได้) ปัญหาในการหลบหนี html ก่อนที่จะแทรกลงในฐานข้อมูลคืออะไร? มีงานอีกรอบไหม?
n00b

ขวา - การหลบหนีก่อนเข้าสู่ฐานข้อมูลนั้นยอดเยี่ยมมาก คุณแค่ต้องการให้แน่ใจว่าคุณไม่มีแฮ็กที่ไม่สามารถหลบหนีได้ก่อนที่คุณจะเพิ่มเข้ามา ...
Kevin

5
ฉันชอบคำพ้องความหมายมากกว่า: CGI.escape_html
Trantor Liu

77

ใน Ruby on Rails 3 HTML จะถูก Escape โดยค่าเริ่มต้น

สำหรับสตริงที่ไม่ใช้ Escape ให้ใช้:

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

25

ERB :: Util.html_escapeสามารถใช้ได้ทุกที่ สามารถใช้ได้โดยไม่ต้องใช้requireใน Rails


นี้เป็นจริงโดยใช้CGI.escapeHTMLใต้
akostadinov

@akostadinov - ผลลัพธ์แตกต่างกันอย่างไร ตัวอย่างเช่น ERB :: Util.html_escape จะเปลี่ยนเครื่องหมายวรรคตอนเป็น & # x27; ในขณะที่ CGI :: escapeHTML จะไม่
Louis Sayers

@LouisSayers ฉันไม่เห็นว่ามันเกิดขึ้นได้อย่างไร: `` [43] แงะ (หลัก)> show-source ERB :: Util.html_escape From: /usr/share/ruby/erb.rb @ line 945: Owner : # <Class: ERB :: Util> Visibility: public จำนวนบรรทัด: 3 def html_escape (s) CGI.escapeHTML (s.to_s) end ``
akostadinov

@akostadinov - อืม ... เพิ่งวิ่งอีกครั้งและใช่พวกเขาให้ผลลัพธ์เดียวกัน ฉันสาบานว่าสิ่งนี้ให้ผลลัพธ์ที่แตกต่างกันเมื่อฉันใช้งานสิ่งนี้ในที่ทำงาน (อาจแตกต่างจากพฤติกรรมของเวอร์ชัน erb / cgi?) ฉันจะต้องดูว่าทำไมพรุ่งนี้ฉันถึงได้ผลลัพธ์ที่แตกต่างออกไป
Louis Sayers

17

นอกเหนือจากคำตอบของ Christopher Bradford ในการใช้ HTML ที่หลีกเลี่ยงได้ทุกที่เนื่องจากคนส่วนใหญ่ไม่ได้ใช้CGIในปัจจุบันคุณยังสามารถใช้Rack:

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

มีวิธีที่ดีกว่าในการหลีกเลี่ยงสตริงในลักษณะเดียวกันในวิธีการอินสแตนซ์แบบจำลองหรือไม่
เข้ารหัสใช้งาน

16

คุณสามารถใช้อย่างใดอย่างหนึ่งh()หรือhtml_escape()แต่คนส่วนใหญ่ใช้h()ตามแบบแผน h()สั้นสำหรับhtml_escape()ราง

ในตัวควบคุมของคุณ:

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

ในมุมมองของคุณ:

<%=h @stuff %>

หากคุณดูซอร์ส HTML: คุณจะเห็นผลลัพธ์โดยไม่ต้องทำให้ข้อมูลเป็นตัวหนา &lt;b&gt;Hello World!&lt;/b&gt;คือมันจะถูกเข้ารหัสเป็น

จะปรากฏขึ้นแสดงเป็น <b>Hello World!</b>


10

การเปรียบเทียบวิธีการต่างๆ:

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

ฉันเขียนของตัวเองเพื่อให้เข้ากันได้กับ Rails ActiveMailer Escapeing:

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

0

h() ยังมีประโยชน์สำหรับการหลีกเลี่ยงเครื่องหมายคำพูด

result[r].thtitleตัวอย่างเช่นผมมีมุมมองที่สร้างการเชื่อมโยงโดยใช้ฟิลด์ข้อความ ข้อความอาจมีเครื่องหมายคำพูดเดี่ยว หากฉันไม่ได้หลบหนีresult[r].thtitleในวิธีการยืนยัน Javascript จะทำลาย:

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

หมายเหตุ: การ:htmlประกาศชื่อจะถูกหลีกหนีอย่างน่าอัศจรรย์โดย Rails

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.