HTML:清理一组标记但允许<code> blocks</code>中的所有标记

时间:2012-04-13 03:01:18

标签: django markdown html-sanitizing

我正在使用Django + Markdown来处理用户输入。降价过滤器产生的文本需要是“安全的”,并且不受django的自动转义机制的保护,所以我必须自己逃避用户输入。这就是我现在的做法:

{{ text|force_escape|markdown:"codehilite" }}

但是,如果text包含通过降价标记为<code>的内容,则它也会被转义并且输出会非常难看(例如,'&lt;'显示为{{在&lt;)中的1}}。例如,如果

<code>

使用上述过滤器,生成的文本为:

text = u'''
       <script>alert("I'm not working 'cause I'll be escaped")</script>
       The following would be marked as a code block:

           <script>alert("not xss 'cause I'm in <code>")</script>

'''

我的意思是:

<p>
    &lt;script&gt;alert("I'm not working 'cause I'll be escaped")&lt;/script&gt;
    The following would be marked as a code block:
</p>
<pre class="codehilite">
    <code>
        &amp;lt;script&amp;gt;alert(&amp;quot;not xss &amp;#39;cause I&amp;#39;m in &amp;lt;code&amp;gt;&amp;quot;)&amp;lt;/script&amp;gt;
    </code>
</pre>

我正在考虑使用BeautifulSoup来获取markdown生成的<p> &lt;script&gt;alert("I'm not working 'cause I'll be escaped")&lt;/script&gt; The following would be marked as a code block: </p> <pre class="codehilite"> <code> <script>alert("not xss 'cause I'm in <code>")</script> </code> </pre> 块并反向转义其内容。但<code>仅返回“文字”,不包括标签。所以我无法抓住其中任何一个soup.code.text ..

1 个答案:

答案 0 :(得分:0)

在将输入传递给Markdown之前不要转义输入。如您所见,在某些情况下会破坏用户输入。并且,它不能确保安全性:例如,考虑“[clickme](javascript:alert%28%22xss%22%29)”。

相反,正确的方法是在其安全模式下使用Markdown。我写了elsewhere关于如何这样做,但Django中的简短版本是使用像{{ text | markdown:"safe" }}这样的东西。 (或者,您可以将HTML清理程序(如HTML Purifier)应用于Markdown处理器的输出。)