Як кодувати HTML / виводити рядок? Чи є вбудований?


98

У мене є ненадійний рядок, який я хочу показати як текст на сторінці HTML. Мені потрібно уникнути символів ' <' і ' &' як HTML-сутності. Чим менше метушні, тим краще.

Я використовую UTF8 і мені не потрібні інші сутності для наголошених літер.

Чи є вбудована функція в Ruby або Rails, чи я повинен прокручувати власну?


2
Відповідно до OWASP , для належного захисту XSS у вмісті елемента HTML слід &<>"'/
— уникати

Відповіді:


94

hДопоміжний метод:

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

Що ж, він також уникає>, що непотрібно, але це зробить.
— кч

Ви можете використовувати дужки для друку деяких з h, а деяких без. <% = h ("<p") + ">"%>
— Тревор Брамбл

Тепер це було б нерозумно. Мене мало хвилює, врятується він чи ні. Я просто зауважую, що це не потрібно в специфікаціях html.
— кч

12
Це іноді потрібно в XHTML з - за досить дратівливою наполегливістю XML - SPEC, що «]]>» бути видалені з тексту (див виробництво «CharData»). Це робить його взагалі простіше (і нешкідливим) завжди уникати цього.
— bobince

19
Для тих, хто цікавиться 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).
— Alex D

Якщо вміст відображається на веб-сайті клієнта, крім вашого власного (де ви не можете контролювати перегляд), у чому проблема з уникненням HTML перед вставкою в базу даних? Чи є інша робота навколо?
— n00b

Правильно - втеча перед входом до бази даних - це чудово. Ви просто хочете переконатися, що у вас там немає жодних старих невтікаючих хаків, перш ніж ви додали його ...
— Кевін,

5
Мені більше подобається його синонім: CGI.escape_html
— Liu

77

У Ruby on Rails 3 за замовчуванням буде вибрано HTML.

Для незахищених рядків використовуйте:

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

25

ERB :: Util.html_escape можна використовувати будь-де. Він доступний без використання requireв Rails.


це насправді використовується CGI.escapeHTMLвнизу
— akostadinov

@akostadinov - однак результат інший. Наприклад, ERB :: Util.html_escape перетворить апострофи в & # x27; тоді як CGI :: escapeHTML не буде
— Луї Сайерс

@LouisSayers, я не бачу, як це може статися: `` `[43] pry (main)> шоу-джерело ERB :: Util.html_escape Від: /usr/share/ruby/erb.rb @ рядок 945: власник : # <Клас: ERB :: Util> Видимість: public Кількість рядків: 3 def html_escape (s) CGI.escapeHTML (s.to_s) end `` `
— akostadinov

@akostadinov - хм ... Просто знову побіг і так, вони дали такий же вихід. Я клянусь, що це дало різні результати, коли я запускав це на роботі (можливо, інша поведінка версії erb / cgi?). Мені доведеться побачити, чому я завтра отримав інший результат на роботі.
— Луї Сайерс

17

Доповненням до відповіді Крістофера Бредфорда використовувати HTML, що втікає де завгодно, оскільки більшість людей сьогодні не використовують CGI, ви також можете використовувати Rack:

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

Чи є кращий спосіб уникнути рядків подібним чином у методах екземплярів моделі?
— Кодування активне

15

Ви можете використовувати будь-який 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>


9

Порівняння різних методів:

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

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>

Примітка: :htmlRails за допомогою магічної декларації заголовок уникає.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.