
Ruby HTML и CSS санитайзер.
Sanitize — это санитайзер HTML и CSS на основе белого списка. Он удаляет весь HTML и/или CSS из строки, кроме элементов, атрибутов и свойств, которые вы решили разрешить.
Используя простой синтаксис конфигурации, вы можете указать Sanitize разрешать определённые HTML-элементы, определённые атрибуты внутри этих элементов и даже определённые URL-протоколы внутри атрибутов, содержащих URL. Вы также можете разрешать определённые CSS-свойства, @-правила и URL-протоколы в элементах или атрибутах, содержащих CSS. Любой HTML или CSS, который вы явно не разрешили, будет удалён.
Sanitize основан на парсере HTML5 Nokogiri, который разбирает HTML так же, как современные браузеры, и Crass, который разбирает CSS так же, как современные браузеры. Пока ваша конфигурация белого списка разрешает только безопасную разметку и CSS, даже самый некорректный или вредоносный ввод будет преобразован в безопасный вывод.
[!WARNING]
Sanitize не может полностью очистить содержимое элементов
<math>или<svg>. Элементы MathML и SVG являются чужеродными элементами, которые не подчиняются обычным правилам разбора HTML.По умолчанию Sanitize удаляет все элементы MathML и SVG. Если вы добавите элементы MathML или SVG в пользовательский белый список элементов, вы можете создать уязвимость в безопасности вашего приложения.
gem install sanitize
require 'sanitize'
# Clean up an HTML fragment using Sanitize's permissive but safe Relaxed config.
# This also sanitizes any CSS in `<style>` elements or `style` attributes.
Sanitize.fragment(html, Sanitize::Config::RELAXED)
# Clean up an HTML document using the Relaxed config.
Sanitize.document(html, Sanitize::Config::RELAXED)
# Clean up a standalone CSS stylesheet using the Relaxed config.
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
# Clean up some CSS properties using the Relaxed config.
Sanitize::CSS.properties(css, Sanitize::Config::RELAXED)
Sanitize может очищать следующие типы входных данных:
<style>style[!WARNING]
Sanitize не может полностью очистить содержимое элементов
<math>или<svg>. Элементы MathML и SVG являются чужеродными элементами, которые не подчиняются обычным правилам разбора HTML.По умолчанию Sanitize удаляет все элементы MathML и SVG. Если вы добавите элементы MathML или SVG в пользовательский список разрешённых элементов, вы можете создать уязвимость в безопасности вашего приложения.
Фрагмент — это фрагмент HTML-кода, который не содержит корневого элемента <html>.
Если вы не укажете никаких параметров конфигурации, Sanitize по умолчанию будет использовать самые строгие настройки, что означает, что он удалит весь HTML и оставит только безопасный текст.
html = '<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">'
Sanitize.fragment(html)
# => "foo"
Чтобы сохранить определённые элементы, добавьте их в список разрешённых элементов.
Sanitize.fragment(html, elements: ['b'])
# => "<b>foo</b>"
При санитизации документа элемент <html> должен быть в белом списке. Вы также можете установить :allow_doctype в значение true, чтобы разрешить корректно сформированные определения типа документа.
html = %[
<!DOCTYPE html>
<html>
<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">
</html>
]
Sanitize.document(html,
allow_doctype: true,
elements: ['html']
)
# => "<!DOCTYPE html><html>foo\n \n</html>"
Чтобы очистить CSS во фрагменте или документе HTML, сначала добавьте в белый список элемент <style> и/или атрибут style. Затем добавьте в белый список свойства CSS, @-правила и URL-протоколы, которые вы хотите разрешить. Вы также можете выбрать, разрешать ли комментарии CSS или хаки совместимости с браузерами.
html = %[
<style>
div { color: green; width: 1024px; }
</style>
<div style="height: 100px; width: 100px;"></div>
<p>hello!</p>
]
Sanitize.fragment(html,
elements: ['div', 'style'],
attributes: {'div' => ['style']},
css: {
properties: ['width']
}
)
#=> %[
# <style>
# div { width: 1024px; }
# </style>
#
# <div style=" width: 100px;"></div>
# hello!
# ]
Sanitize без проблем очистит автономную таблицу стилей CSS или строку свойств, не вызывая HTML-парсер.
[!WARNING] Это следует использовать только для очистки CSS, предназначенного для отдельного CSS-файла. Чтобы безопасно очистить CSS для использования в контексте HTML, например в элементе
<style>или атрибутеstyle, необходимо использоватьSanitize.document()илиSanitize.fragment()с соответствующим списком разрешённых элементов, как описано в предыдущих разделах. Несоблюдение этого может сделать возможными атаки HTML-инъекций.
css = %[
@import url(evil.css);
a { text-decoration: none; }
a:hover {
left: expression(alert('xss!'));
text-decoration: underline;
}
]
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
# => %[
#
#
# a { text-decoration: none; }
#
# a:hover {
#
# text-decoration: underline;
# }
# ]
Sanitize::CSS.properties(%[
left: expression(alert('xss!'));
text-decoration: underline;
], Sanitize::Config::RELAXED)
# => %[
#
# text-decoration: underline;
# ]
Помимо сверхбезопасных настроек по умолчанию, Sanitize поставляется с тремя другими встроенными конфигурациями, которые можно использовать сразу или адаптировать под свои нужды.
Разрешает только очень простую встроенную разметку. Без ссылок, изображений и блочных элементов.
Sanitize.fragment(html, Sanitize::Config::RESTRICTED)
# => "<b>foo</b>"
Разрешает разнообразную разметку, включая элементы форматирования, ссылки и списки.
Изображения и таблицы не допускаются, ссылки ограничены протоколами FTP, HTTP, HTTPS и mailto, а ко всем ссылкам добавляется атрибут rel="nofollow" для предотвращения SEO-спама.
Sanitize.fragment(html, Sanitize::Config::BASIC)
# => '<b><a href="http://foo.com/" rel="nofollow">foo</a></b>'
Допускает ещё более широкий набор разметки, включая изображения и таблицы, а также безопасный CSS. Ссылки по-прежнему ограничены протоколами FTP, HTTP, HTTPS и mailto, а изображения — только HTTP и HTTPS. В этом режиме rel="nofollow" не добавляется к ссылкам.
Sanitize.fragment(html, Sanitize::Config::RELAXED)
# => '<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">'
Если встроенные режимы не соответствуют вашим потребностям, вы можете легко задать пользовательскую конфигурацию:
Sanitize.fragment(html,
elements: ['a', 'span'],