Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[1.3.X] Fixed #17837. Improved markdown safety.

Markdown enable_attributes is now False when safe_mode is enabled. Documented
the markdown "safe" argument. Added warnings when the safe argument is
passed to versions of markdown which cannot be made safe.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17734 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 1f924cf72d76466a359371267c448d19c4e1352a 1 parent d498033
@PaulMcMillan PaulMcMillan authored
View
17 django/contrib/markup/templatetags/markup.py
@@ -11,6 +11,8 @@
* reStructuredText, which requires docutils from http://docutils.sf.net/
"""
+import warnings
+
from django import template
from django.conf import settings
from django.utils.encoding import smart_str, force_unicode
@@ -65,10 +67,21 @@ def markdown(value, arg=''):
# Unicode support only in markdown v1.7 or above. Version_info
# exist only in markdown v1.6.2rc-2 or above.
- if getattr(markdown, "version_info", None) < (1,7):
+ markdown_vers = getattr(markdown, "version_info", None)
+ if markdown_vers < (1,7):
return mark_safe(force_unicode(markdown.markdown(smart_str(value), extensions, safe_mode=safe_mode)))
else:
- return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
+ if markdown_vers >= (2,1):
+ if safe_mode:
+ return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode, enable_attributes=False))
+ else:
+ return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
+ else:
+ warnings.warn("Versions of markdown prior to 2.1 do not "
+ "support disabling of attributes, no "
+ "attributes have been removed and the result "
+ "is insecure.")
+ return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
else:
return mark_safe(force_unicode(markdown.markdown(smart_str(value))))
markdown.is_safe = True
View
14 django/contrib/markup/tests.py
@@ -60,6 +60,20 @@ def test_markdown(self):
pattern = re.compile("""<p>Paragraph 1\s*</p>\s*<h2>\s*An h2</h2>""")
self.assertTrue(pattern.match(rendered))
+ @unittest.skipUnless(markdown, 'markdown no installed')
+ def test_markdown_attribute_disable(self):
+ t = Template("{% load markup %}{{ markdown_content|markdown:'safe' }}")
+ markdown_content = "{@onclick=alert('hi')}some paragraph"
+ rendered = t.render(Context({'markdown_content':markdown_content})).strip()
+ self.assertTrue('@' in rendered)
+
+ @unittest.skipUnless(markdown, 'markdown no installed')
+ def test_markdown_attribute_enable(self):
+ t = Template("{% load markup %}{{ markdown_content|markdown }}")
+ markdown_content = "{@onclick=alert('hi')}some paragraph"
+ rendered = t.render(Context({'markdown_content':markdown_content})).strip()
+ self.assertFalse('@' in rendered)
+
@unittest.skipIf(markdown, 'markdown is installed')
def test_no_markdown(self):
t = Template("{{ markdown_content|markdown }}")
View
16 docs/ref/contrib/markup.txt
@@ -47,3 +47,19 @@ override the default writer settings. See the `restructuredtext writer
settings`_ for details on what these settings are.
.. _restructuredtext writer settings: http://docutils.sourceforge.net/docs/user/config.html#html4css1-writer
+
+Markdown
+--------
+
+The Python Markdown library supports options named "safe_mode" and
+"enable_attributes". Both relate to the security of the output. To enable both
+options in tandem, the markdown filter supports the "safe" argument.
+
+ {{ markdown_content_var|markdown:"safe" }}
+
+.. warning::
+
+ Versions of the Python-Markdown library prior to 2.1 do not support the
+ optional disabling of attributes and by default they will be included in
+ any output from the markdown filter - a warning is issued if this is the
+ case.
Please sign in to comment.
Something went wrong with that request. Please try again.