
Sanitizzatore HTML e CSS per Ruby.
Sanitize è un sanitizer HTML e CSS basato su allowlist. Rimuove tutto l'HTML e/o il CSS da una stringa, ad eccezione degli elementi, degli attributi e delle proprietà che scegli di consentire.
Utilizzando una semplice sintassi di configurazione, puoi indicare a Sanitize di consentire determinati elementi HTML, determinati attributi all'interno di tali elementi e persino determinati protocolli URL all'interno di attributi che contengono URL. Puoi anche consentire specifiche proprietà CSS, regole @ e protocolli URL in elementi o attributi contenenti CSS. Qualsiasi HTML o CSS che non consenti esplicitamente verrà rimosso.
Sanitize si basa sul parser HTML5 Nokogiri, che analizza l'HTML allo stesso modo dei browser moderni, e su Crass, che analizza il CSS allo stesso modo dei browser moderni. Finché la tua configurazione dell'allowlist consente solo markup e CSS sicuri, anche l'input più malformato o malevolo verrà trasformato in output sicuro.
[!WARNING]
Sanitize non è in grado di sanitizzare completamente il contenuto degli elementi
<math>o<svg>. Gli elementi MathML e SVG sono foreign elements che non seguono le normali regole di parsing HTML.Per impostazione predefinita, Sanitize rimuove tutti gli elementi MathML e SVG. Se aggiungi elementi MathML o SVG a un'allowlist personalizzata di elementi, potresti creare una vulnerabilità di sicurezza nella tua applicazione.
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 può sanificare i seguenti tipi di input:
<style>style[!WARNING]
Sanitize non può sanificare completamente il contenuto degli elementi
<math>o<svg>. Gli elementi MathML e SVG sono elementi estranei che non seguono le normali regole di parsing HTML.Per impostazione predefinita, Sanitize rimuoverà tutti gli elementi MathML e SVG. Se aggiungi elementi MathML o SVG a una allowlist personalizzata di elementi, potresti creare una vulnerabilità di sicurezza nella tua applicazione.
Un frammento è uno snippet di HTML che non contiene un elemento <html> a livello radice.
Se non specifichi alcuna opzione di configurazione, Sanitize utilizzerà per impostazione predefinita le sue impostazioni più restrittive, il che significa che rimuoverà tutto l'HTML lasciando dietro di sé solo testo sicuro.
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"
Per mantenere determinati elementi, aggiungili alla allowlist degli elementi.
Sanitize.fragment(html, elements: ['b'])
# => "<b>foo</b>"
Quando si esegue la sanitizzazione di un documento, l'elemento <html> deve essere inserito nella allowlist. È inoltre possibile impostare :allow_doctype su true per consentire definizioni di tipo di documento ben formate.
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>"
Per sanificare il CSS in un frammento o documento HTML, occorre prima inserire nella allowlist l'elemento <style> e/o l'attributo style. Poi inserire nella allowlist le proprietà CSS, le regole @ e i protocolli URL che si desidera consentire. È inoltre possibile scegliere se consentire i commenti CSS o gli hack di compatibilità con i browser.
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 ripulisce senza problemi un foglio di stile CSS autonomo o una stringa di proprietà senza dover invocare il parser HTML.
[!WARNING] Questo dovrebbe essere usato solo per sanitizzare CSS da utilizzare in un file CSS autonomo. Per sanitizzare in modo sicuro il CSS da usare in un contesto HTML, come in un elemento
<style>o in un attributostyle, è necessario usareSanitize.document()oSanitize.fragment()con un'allowlist appropriata come descritto nelle sezioni precedenti. In caso contrario si potrebbero abilitare attacchi di HTML injection.
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;
# ]
Oltre alle impostazioni predefinite ultra-sicure, Sanitize viene fornito con altre tre configurazioni integrate che puoi utilizzare così come sono o adattare alle tue esigenze.
Consente solo markup inline molto semplice. Nessun link, immagine o elemento di blocco.
Sanitize.fragment(html, Sanitize::Config::RESTRICTED)
# => "<b>foo</b>"
Consente una varietà di markup, inclusi elementi di formattazione, link ed elenchi.
Immagini e tabelle non sono consentite, i link sono limitati ai protocolli FTP, HTTP, HTTPS e mailto, e un attributo rel="nofollow" viene aggiunto a tutti i link per mitigare lo spam SEO.
Sanitize.fragment(html, Sanitize::Config::BASIC)
# => '<b><a href="http://foo.com/" rel="nofollow">foo</a></b>'
Consente una varietà ancora più ampia di markup, incluse immagini e tabelle, oltre a CSS sicuro. I link sono comunque limitati ai protocolli FTP, HTTP, HTTPS e mailto, mentre le immagini sono limitate a HTTP e HTTPS. In questa modalità, rel="nofollow" non viene aggiunto ai link.
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">'