2

I'm trying to print out HTML generated for user-submitter markdown, by

{{=markdown(post.message)}}

where markdown function is imported through

from gluon.contrib.markdown.markdown2 import markdown

We2Py seems to automatically encode HTML-Entities, so every < is converted into &lt; and every > is converted into &gt;. How do I prevent this from happening?

Are there any security concerns that I'll need to keep in mind while doing so? Also, could anyone kindly tell me how can I strip the HTML when storing it in the database, while retaining the markdown?

S P
  • 1,801
  • 6
  • 32
  • 55

1 Answers1

9

You have to do this:

{{=XML(markdown(post.message))}}

every string is sanitized by template render, if you pass "<div>" it will be rendered as "&lt;div&gt;" it is to protect against malicious code.

When you pass a string to XML helper XML("<div>") it uses an XML parser to render the string in to an XML tree structure,XML has a method .xml() which returns the unescaped string to the response.body so the user's browser have the correct html.

you can control some parameters of XML rendering.

:param text: the XML text
:param sanitize: sanitize text using the permitted tags and allowed attributes (default False)
:param permitted_tags: list of permitted tags (default: simple list of tags)
:param allowed_attributes: dictionary of allowed attributed
S P
  • 1,801
  • 6
  • 32
  • 55
  • What if a user submits a similar XML tree structure with a script? I mean how does web2py differentiate between its `XML` output and user-submitted ones? – S P Mar 13 '12 at 08:05
  • 1
    Users can only submit text, and all text is escaped by default. The only way to avoid this is to pass the text to the web2py `XML()` helper class, which knows how to render itself without escaping. Users have no way to submit an instance of the `XML` helper class. Note, in this case, when we say `XML` helper, we mean a Python class called "XML", which is part of web2py, not a generic string that happens to be valid XML (if the user submits such a string, it will still be escaped). – Anthony Mar 13 '12 at 13:51
  • Is there someway to set `permitted_tags` and `allowed_attributes` globally, so that I don't need to add them everywhere? For now I'm using a function (`def my_xml(st): return XML(st, sanitize=True,...)`) imported in my models for global use – S P Apr 14 '12 at 09:41