Markdown in Django XSS safe

2019-02-19 06:34发布

问题:

I am using Markdown in an app to display a user biography. I want the user to be able to slightly format the biography, so I'm letting them use the TinyMCE editor.

Then, displaying it in the Django Template like this

{% load markup %}

<div id="biography">
    {{ biography|markdown }}
</div>

The problem is, if there is a tag in the biography, it is not being escaped as django does everywhere else. This is the source output from a biography test:

<p><strong>asdfsdafsadf</strong></p> 
<p><strong>sd<em>fdfdsfsd</em></strong><em>sdfsdfsdfdsf</em>sdfsdfsdf</p> 
<p><strong>sdafasdfasdf</strong></p> 

<script>document.location='http://test.com'</script> 

How do I set Markdown to escape these malicious scripts?

回答1:

According to django.contrib.markup.templatetags.markup.markdown's docstrings:

To enable safe mode, which strips raw HTML and only returns HTML generated by actual Markdown syntax, pass "safe" as the first extension in the list.

This should work:

{{ biography|markdown:"safe" }}


回答2:

Markdown in safe mode would remove all html tags, which means your users cannot input HTML segments in the biography. In some cases, this is not preferable. I would recommend you use force_escape before markdown, so anything fed into markdown is safe.

For example, if your biography is <html>I'm really a HTML fan!</html>, using

{{ biography|markdown:"safe"}}

would produce HTML REMOVED.. Instead, if you use

{{ biography|force_escape|markdown }}

The output would be something like

<p>&lt;html&gt;I'm really a HTML fan!&lt;/html&gt</p>