mirror of
				https://github.com/django/django.git
				synced 2025-10-31 16:07:30 +03:00 
			
		
		
		
	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. Deprecated versions of markdown < 2.1. Many thanks to ptone for the patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@17735 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		
							parent
							
								
									eb9eaa6d71
								
							
						
					
					
						commit
						14df122f86
					
				|  | @ -11,6 +11,8 @@ markup syntaxes to HTML; currently there is support for: | |||
|     * 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 | ||||
|  | @ -63,14 +65,25 @@ def markdown(value, arg=''): | |||
|                 safe_mode = True | ||||
|             else: | ||||
|                 safe_mode = False | ||||
| 
 | ||||
|             python_markdown_deprecation = "The use of Python-Markdown " | ||||
|             "< 2.1 in Django is deprecated; please update to the current version" | ||||
|             # 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): | ||||
|                 warnings.warn(python_markdown_deprecation, DeprecationWarning) | ||||
|                 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(python_markdown_deprecation, DeprecationWarning) | ||||
|                     return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode)) | ||||
|         else: | ||||
|             warnings.warn(python_markdown_deprecation, DeprecationWarning) | ||||
|             return mark_safe(force_unicode(markdown.markdown(smart_str(value)))) | ||||
| 
 | ||||
| @register.filter(is_safe=True) | ||||
|  |  | |||
|  | @ -58,6 +58,20 @@ Paragraph 2 with a link_ | |||
|         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("{% load markup %}{{ markdown_content|markdown }}") | ||||
|  |  | |||
|  | @ -196,6 +196,11 @@ these changes. | |||
|   filesystem path to a ``locale`` directory containing non-app-specific | ||||
|   translations in its value. | ||||
| 
 | ||||
| * The Markup contrib app will no longer support versions of Python-Markdown | ||||
|   library earlier than 2.1. An accelerated timeline was used as this was | ||||
|   a security related deprecation. | ||||
| 
 | ||||
| 
 | ||||
| 1.6 | ||||
| --- | ||||
| 
 | ||||
|  |  | |||
|  | @ -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. | ||||
|  |  | |||
|  | @ -1096,6 +1096,16 @@ field. This was something that should not have worked, and in 1.4 loading such | |||
| incomplete fixtures will fail. Because fixtures are a raw import, they should | ||||
| explicitly specify all field values, regardless of field options on the model. | ||||
| 
 | ||||
| Attributes disabled in markdown when safe mode set | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| Prior to Django 1.4, attributes were included in any markdown output regardless | ||||
| of safe mode setting of the filter. With version > 2.1 of the Python-Markdown | ||||
| library, an enable_attributes option was added. When the safe argument is | ||||
| passed to the markdown filter, both the ``safe_mode=True`` and | ||||
| ``enable_attributes=False`` options are set. If using a version of the | ||||
| Python-Markdown library less than 2.1, a warning is issued that the output is | ||||
| insecure. | ||||
| 
 | ||||
| Features deprecated in 1.4 | ||||
| ========================== | ||||
|  | @ -1262,3 +1272,12 @@ each request to a site map now creates a new Paginator object and calls the | |||
| ``items()`` method is doing, this may have a negative performance impact. | ||||
| To mitigate the performance impact, consider using the :doc:`caching | ||||
| framework </topics/cache>` within your ``Sitemap`` subclass. | ||||
| 
 | ||||
| Versions of Python-Markdown earlier than 2.1 | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| Versions of Python-Markdown earlier than 2.1 do not support the option to | ||||
| disable attributes. As a security issue, earlier versions of this library will | ||||
| not be supported by the markup contrib app in 1.5 under an accelerated | ||||
| deprecation timeline. | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user