2

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?

Brenden
  • 8,264
  • 14
  • 48
  • 78

2 Answers2

3

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" }}
Zach Kelling
  • 52,505
  • 13
  • 109
  • 108
  • is there an easy way to handle the situation where `biography` contained an HTML code sample that you wanted displayed? – mr_c Jun 27 '13 at 16:56
-1

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>
blurrcat
  • 1,278
  • 13
  • 23
  • This seems like a natural approach, but I believe it is actually insecure. Example: "`[clickme](javascript:alert%28%22xss%22%29)`". For more details, see my explanation [elsewhere](http://security.stackexchange.com/a/14674/971). – D.W. May 06 '12 at 21:34
  • @D.W. `markdown(html, safe_mode='escape')` seems to work perfectly for me right now. Is there a problem? – blurrcat May 07 '12 at 00:49
  • Yes. You recommended `force_escape|markdown`, and the problem is that's insecure: that does not invoke Markdown with the safe flag and thus will be insecure against the sort of attack I described. See the link I gave for a detailed explanation. Try `markdown(force_escape("[clickme](javascript:alert%28%22xss%22%29)"))`" to see what I mean; the result has Javascript in it. – D.W. May 07 '12 at 03:16