Utilizzo consigliato. La risposta breve è: utilizza markdown(untrusted, safe_mode=remove, enable_attributes=False)
.
Assicurati di avere una versione aggiornata della libreria Markdown, in quanto le versioni precedenti presentano alcuni problemi di sicurezza.
Potresti anche eseguire l'output tramite un disinfettante HTML, come HTML Purifier.
Motivazione. È una buona idea disabilitare enable_attributes
. Mentre le ultime versioni di sviluppo della libreria di markdown di Python saranno disabilitano enable_attributes
di default se imposti safe_mode
, le versioni precedenti non lo facevano. Di conseguenza, l'impostazione di safe_mode
è non sufficiente sulla maggior parte delle versioni della libreria Markdown . Se hai appena impostato safe_mode
, il risultato non è sicuro:
import markdown
>>> markdown.markdown("{@onclick=alert('hi')}some paragraph", safe_mode=True)
u'<p onclick="alert(\'hi\')">some paragraph</p>'
Al momento, le correzioni sono presenti solo in git. Al momento della stesura di questo documento, l'ultima versione rilasciata di Python Markdown (2.1.1) rimane vulnerabile a meno che non si imposti esplicitamente enable_attributes=False
. Pertanto, è plausibile che molti sistemi che attualmente utilizzano Python Markdown possano essere vulnerabili.
La documentazione potrebbe essere migliore per avvisare gli utenti di Markdown riguardo a questi problemi. Dice cose come "Si potrebbe anche voler impostare enable_attributes=False
quando si usa safe_mode
", senza rivelare che non riuscendo a farlo si crea un buco XSS con tutte le ultime versioni della libreria. Versioni successive della documentazione dicono che l'impostazione di enable_attributes
"potrebbe potenzialmente consentire ad un utente non fidato di inserire JavaScript nei tuoi documenti"; sarebbe più chiaro dire che l'impostazione enable_attributes
consente agli utenti di iniettare JavaScript nei tuoi documenti ed è quindi molto insicuro se il Markdown provenga da una fonte non attendibile.
Dubbi. Detto questo, non sono sicuro al 100% se il risultato sarà sicuro, anche quando lo utilizzi come raccomandato sopra. Gli sviluppatori hanno fatto commenti come il seguente:
"safe-mode" was a poor name choice that we continue to use for backward comparability (old code still works with our newer versions). What it really is is a no-markup mode. In other words, it is just a way to disallow raw html and really doesn't guarantee safety.
Quei tipi di commenti sono un po 'spaventosi.
Nelle precedenti versioni della libreria Python Markdown, la sua sanitizzazione HTML mi sembra un po 'fragile, quindi non sono sicuro se mi fiderei delle versioni precedenti della libreria Markdown, indipendentemente da quali flag vengono passati. Considera quanto segue:
>>> markdown.markdown("[Example](javascript://alert%28%22xss%22%29)", safe_mode=True)
u'<p><a href="javascript://alert%28%22xss%22%29">Example</a></p>'
Consentire agli URL javascript:
-style tramite l'elaborazione di Markdown mi sembra una decisione di design piuttosto discutibile. Sembra che si tratti di un salto, di un salto e di un salto di XSS. Tutto ciò che manca è un modo per rompere il commento in stile C ++ (il //
), ed è game over. Ad esempio:
>>> markdown.markdown("[Example](javascript://\nalert%28%22xss%22%29)", safe_mode=True)
u'<p><a href="javascript:// alert%28%22xss%22%29">Example</a></p>'
Quanto dovrei essere sicuro che nessun browser eseguirà quel Javascript? Non so, ma non mi sta dando sensazioni calde e confuse. Se è sicuro, è solo cieca fortuna.
Fortunatamente, l'ultima versione rilasciata di Markdown sembra fare un filtraggio più rigoroso dello script se si imposta enable_attributes=False
. Ma assicurati di impostare enable_attributes=False
, altrimenti Markdown ricade sulla fragile sanitizzazione HTML trovata nelle versioni precedenti e non sono sicuro della sicurezza di tale schema.
Cosa non fare. Quanto segue non è sicuro: markdown(escape(untrusted))
.
- Si potrebbe pensare che prima di sfuggire l'input rimuoverebbe tutto l'HTML e rendere questo uso sicuro. In effetti ho visto questo usato in alcuni sistemi e raccomandato da alcuni. Tuttavia, in realtà non è sicuro, poiché l'escaping non è sufficiente per rendere sicuri gli URL. Ad esempio, questo utilizzo di Markdown può essere sconfitto da "
[clickme](javascript:alert%28%22xss%22%29)
". In generale, sfuggire l'input a Markdown è non l'approccio giusto ; l'approccio giusto è invocare Markdown nel modo appropriato (e possibilmente applicare anche un filtro HTML al suo output, se vuoi una protezione extra).
Se usi Django. Se usi Django, il seguente dovrebbe essere un modo sicuro per usare Markdown:
{{ untrusted | markdown:"safe" }}
A partire da Django 1.4 , questo è sicuro. quando passi l'argomento "safe"
, Django ora ha un supporto speciale per impostare safe_mode
e disabilitare enable_attributes
. Ma assicurati di aggiornare a Django 1.4 o versioni successive; nelle versioni precedenti, questo utilizzo non era sicuro .