From 67d8cf383120952da9ed5bc7d49e22cee8fd984f Mon Sep 17 00:00:00 2001 From: benjaoming Date: Sun, 3 Feb 2013 19:52:33 +0100 Subject: [PATCH] Security fix, do not call eval on input --- wiki/plugins/images/markdown_extensions.py | 1 + wiki/plugins/links/mdx/djangowikilinks.py | 1 + wiki/plugins/links/mdx/urlize.py | 1 + wiki/plugins/macros/markdown_extensions.py | 26 +++++++++++++++++++--- wiki/plugins/macros/settings.py | 1 + 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/wiki/plugins/images/markdown_extensions.py b/wiki/plugins/images/markdown_extensions.py index e4540acf..8ca96409 100644 --- a/wiki/plugins/images/markdown_extensions.py +++ b/wiki/plugins/images/markdown_extensions.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import markdown import re diff --git a/wiki/plugins/links/mdx/djangowikilinks.py b/wiki/plugins/links/mdx/djangowikilinks.py index 205e4c63..fb319f98 100755 --- a/wiki/plugins/links/mdx/djangowikilinks.py +++ b/wiki/plugins/links/mdx/djangowikilinks.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- ''' Wikipath Extension for Python-Markdown diff --git a/wiki/plugins/links/mdx/urlize.py b/wiki/plugins/links/mdx/urlize.py index ea52d20b..c84db8ca 100644 --- a/wiki/plugins/links/mdx/urlize.py +++ b/wiki/plugins/links/mdx/urlize.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Code modified from: https://github.com/r0wb0t/markdown-urlize diff --git a/wiki/plugins/macros/markdown_extensions.py b/wiki/plugins/macros/markdown_extensions.py index 9940a9fe..75e75e61 100644 --- a/wiki/plugins/macros/markdown_extensions.py +++ b/wiki/plugins/macros/markdown_extensions.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import markdown import re @@ -5,8 +6,11 @@ from django.utils.translation import ugettext as _ from django.template.loader import render_to_string from django.template import Context +# See: http://stackoverflow.com/questions/430759/regex-for-managing-escaped-characters-for-items-like-string-literals +re_sq_short = r"'([^'\\]*(?:\\.[^'\\]*)*)'" + MACRO_RE = re.compile(r'.*(\[(?P\w+)(?P\s\w+\:.+)*\]).*', re.IGNORECASE) -KWARG_RE = re.compile(r'([^ |:]+):([^ |$]+)', re.IGNORECASE) +KWARG_RE = re.compile(r'\s*(?P\w+)(:(?P([^\']|%s)))?' % re_sq_short, re.IGNORECASE) from wiki.plugins.macros import settings @@ -25,6 +29,9 @@ class MacroPreprocessor(markdown.preprocessors.Preprocessor): allowed_methods = settings.METHODS def run(self, lines): + # Look at all those indentations. + # That's insane, let's get a helper library + # Please note that this pattern is also in plugins.images new_text = [] for line in lines: m = MACRO_RE.match(line) @@ -33,8 +40,21 @@ class MacroPreprocessor(markdown.preprocessors.Preprocessor): if macro in MacroPreprocessor.allowed_methods: kwargs = m.group('kwargs') if kwargs: - kwargs = eval('{' + KWARG_RE.sub(r'"\1":"\2",', kwargs) + '}') - line = getattr(self, macro)(**kwargs) + kwargs_dict = {} + for kwarg in KWARG_RE.finditer(kwargs): + arg = kwarg.group('arg') + value = kwarg.group('value') + if value is None: + value = True + if isinstance(value, basestring): + # If value is enclosed with ': Remove and remove escape sequences + if value.startswith(u"'") and len(value) > 2: + value = value[1:-1] + value = value.replace(u"\\\\", u"¤KEEPME¤") + value = value.replace(u"\\", u"") + value = value.replace(u"¤KEEPME¤", u"\\") + kwargs_dict[arg] = value + line = getattr(self, macro)(**kwargs_dict) else: line = getattr(self, macro)() if not line is None: diff --git a/wiki/plugins/macros/settings.py b/wiki/plugins/macros/settings.py index bfc262e0..28a29ca8 100644 --- a/wiki/plugins/macros/settings.py +++ b/wiki/plugins/macros/settings.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from django.conf import settings as django_settings SLUG = 'macros' -- 2.45.2