
Ruby sanitizador de HTML e CSS.
Sanitize é um sanitizador de HTML e CSS baseado em allowlist. Ele remove todo o HTML e/ou CSS de uma string, exceto os elementos, atributos e propriedades que você optar por permitir.
Usando uma sintaxe de configuração simples, você pode instruir o Sanitize a permitir determinados elementos HTML, determinados atributos dentro desses elementos e até mesmo determinados protocolos de URL em atributos que contenham URLs. Você também pode permitir propriedades CSS específicas, regras @ e protocolos de URL em elementos ou atributos que contenham CSS. Qualquer HTML ou CSS que você não permitir explicitamente será removido.
O Sanitize é baseado no parser HTML5 Nokogiri, que analisa HTML da mesma forma que os navegadores modernos, e no Crass, que analisa CSS da mesma forma que os navegadores modernos. Desde que sua configuração de allowlist permita apenas marcação e CSS seguros, mesmo a entrada mais malformada ou maliciosa será transformada em saída segura.
[!WARNING]
O Sanitize não consegue sanitizar completamente o conteúdo de elementos
<math>ou<svg>. Elementos MathML e SVG são elementos estrangeiros que não seguem as regras normais de análise de HTML.Por padrão, o Sanitize removerá todos os elementos MathML e SVG. Se você adicionar elementos MathML ou SVG a uma allowlist de elementos personalizada, poderá criar uma vulnerabilidade de segurança em sua aplicação.
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)
O Sanitize pode sanitizar os seguintes tipos de entrada:
<style>style[!WARNING]
O Sanitize não consegue sanitizar completamente o conteúdo de elementos
<math>ou<svg>. Elementos MathML e SVG são elementos estrangeiros que não seguem as regras normais de análise do HTML.Por padrão, o Sanitize removerá todos os elementos MathML e SVG. Se você adicionar elementos MathML ou SVG a uma lista de permissões de elementos personalizada, poderá criar uma vulnerabilidade de segurança em sua aplicação.
Um fragmento é um trecho de HTML que não contém um elemento <html> no nível raiz.
Se você não especificar nenhuma opção de configuração, o Sanitize usará suas configurações mais restritivas por padrão, o que significa que ele removerá todo o HTML e deixará apenas texto seguro.
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"
Para manter certos elementos, adicione-os à lista de permissões de elementos.
Sanitize.fragment(html, elements: ['b'])
# => "<b>foo</b>"
Ao sanitizar um documento, o elemento <html> deve estar na lista de permissões. Você também pode definir :allow_doctype como true para permitir definições de tipo de documento bem formadas.
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>"
Para sanitizar CSS em um fragmento ou documento HTML, primeiro permita o elemento <style> e/ou o atributo style na lista de permissões. Em seguida, permita as propriedades CSS, as regras @ e os protocolos de URL que você deseja permitir. Você também pode escolher se deseja permitir comentários CSS ou hacks de compatibilidade com navegadores.
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!
# ]
O Sanitize limpará sem problemas uma folha de estilos CSS autônoma ou uma string de propriedades sem precisar invocar o parser HTML.
[!WARNING] Isso deve ser usado apenas para sanitizar CSS para uso em um arquivo CSS autônomo. Para sanitizar CSS com segurança para uso em um contexto HTML, como em um elemento
<style>ou em um atributostyle, você deve usarSanitize.document()ouSanitize.fragment()com uma allowlist apropriada, conforme descrito nas seções anteriores. O não cumprimento disso pode permitir ataques de injeção de 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;
# ]
Além das configurações padrão ultra-seguras, o Sanitize vem com três outras configurações integradas que você pode usar prontas para uso ou adaptar para atender às suas necessidades.
Permite apenas marcação inline muito simples. Sem links, imagens ou elementos de bloco.
Sanitize.fragment(html, Sanitize::Config::RESTRICTED)
# => "<b>foo</b>"
Permite uma variedade de marcação, incluindo elementos de formatação, links e listas.
Imagens e tabelas não são permitidas, os links são limitados aos protocolos FTP, HTTP, HTTPS e mailto, e um atributo rel="nofollow" é adicionado a todos os links para mitigar spam de SEO.
Sanitize.fragment(html, Sanitize::Config::BASIC)
# => '<b><a href="http://foo.com/" rel="nofollow">foo</a></b>'
Permite uma variedade ainda maior de marcação, incluindo imagens e tabelas, bem como CSS seguro. Os links ainda estão limitados aos protocolos FTP, HTTP, HTTPS e mailto, enquanto as imagens estão limitadas a HTTP e HTTPS. Neste modo, rel="nofollow" não é adicionado aos links.
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">'