diff -Nru jinja2-2.6/debian/changelog jinja2-2.6/debian/changelog --- jinja2-2.6/debian/changelog 2014-07-22 15:18:16.000000000 +0000 +++ jinja2-2.6/debian/changelog 2019-05-15 13:41:15.000000000 +0000 @@ -1,3 +1,21 @@ +jinja2 (2.6-1ubuntu0.2) precise-security; urgency=medium + + [ Marc Deslauriers ] + * SECURITY UPDATE: sandbox escape via str.format + - debian/patches/CVE-2016-10745-1.patch: support sandboxing in format + expressions in jinja2/nodes.py, jinja2/sandbox.py. + - debian/patches/CVE-2016-10745-2.patch: fix a name error for an + uncommon attribute access in the sandbox in jinja2/sandbox.py. + - debian/patches/CVE-2016-10745-3.patch: adding types and EscapeFormatter + class to support the fixes from this CVE in jinja2/sandbox.py. + - CVE-2016-10745 + * SECURITY UPDATE: sandbox escape via str.format_map + - debian/patches/CVE-2019-10906.patch: properly sandbox format_map in + jinja2/sandbox.py. + - CVE-2019-10906 + + -- Leonidas S. Barbosa Wed, 15 May 2019 10:40:54 -0300 + jinja2 (2.6-1ubuntu0.1) precise-security; urgency=medium * SECURITY UPDATE: insecure temp dir usage diff -Nru jinja2-2.6/debian/patches/CVE-2016-10745-1.patch jinja2-2.6/debian/patches/CVE-2016-10745-1.patch --- jinja2-2.6/debian/patches/CVE-2016-10745-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ jinja2-2.6/debian/patches/CVE-2016-10745-1.patch 2019-05-15 13:40:23.000000000 +0000 @@ -0,0 +1,201 @@ +Backport of: + +From 9b53045c34e61013dc8f09b7e52a555fa16bed16 Mon Sep 17 00:00:00 2001 +From: Armin Ronacher +Date: Thu, 29 Dec 2016 14:13:38 +0100 +Subject: [PATCH] SECURITY: support sandboxing in format expressions +diff --git a/jinja2/nodes.py b/jinja2/nodes.py +index f9da1da..addee6a 100644 +--- a/jinja2/nodes.py ++++ b/jinja2/nodes.py +@@ -595,7 +595,7 @@ class Call(Expr): + + def as_const(self, eval_ctx=None): + eval_ctx = get_eval_context(self, eval_ctx) +- if eval_ctx.volatile: ++ if eval_ctx.volatile or eval_ctx.environment.sandboxed: + raise Impossible() + obj = self.node.as_const(eval_ctx) + +diff --git a/jinja2/sandbox.py b/jinja2/sandbox.py +index a1cbb29..f80c714 100644 +--- a/jinja2/sandbox.py ++++ b/jinja2/sandbox.py +@@ -12,12 +12,29 @@ + :copyright: (c) 2010 by the Jinja Team. + :license: BSD. + """ ++import types + import operator ++from collections import Mapping + from jinja2.environment import Environment + from jinja2.exceptions import SecurityError + from jinja2.utils import FunctionType, MethodType, TracebackType, CodeType, \ + FrameType, GeneratorType + ++# Adding text_type in support to CVE-2016-10745 ++import sys ++ ++PY2 = sys.version_info[0] == 2 ++ ++if not PY2: ++ text_type = str ++else: ++ text_type = unicode ++ ++has_format = False ++if hasattr(text_type, 'format'): ++ from markupsafe import EscapeFormatter ++ from string import Formatter ++ has_format = True + + #: maximum number of items a range may produce + MAX_RANGE = 100000 +@@ -29,6 +46,12 @@ UNSAFE_FUNCTION_ATTRIBUTES = set(['func_closure', 'func_code', 'func_dict', + #: unsafe method attributes. function attributes are unsafe for methods too + UNSAFE_METHOD_ATTRIBUTES = set(['im_class', 'im_func', 'im_self']) + ++#: unsafe attributes on coroutines ++UNSAFE_COROUTINE_ATTRIBUTES = set(['cr_frame', 'cr_code']) ++ ++#: unsafe attributes on async generators ++UNSAFE_ASYNC_GENERATOR_ATTRIBUTES = set(['ag_code', 'ag_frame']) ++ + + import warnings + +@@ -86,6 +109,48 @@ _mutable_spec = ( + ) + + ++class _MagicFormatMapping(Mapping): ++ """This class implements a dummy wrapper to fix a bug in the Python ++ standard library for string formatting. ++ ++ See http://bugs.python.org/issue13598 for information about why ++ this is necessary. ++ """ ++ ++ def __init__(self, args, kwargs): ++ self._args = args ++ self._kwargs = kwargs ++ self._last_index = 0 ++ ++ def __getitem__(self, key): ++ if key == '': ++ idx = self._last_index ++ self._last_index += 1 ++ try: ++ return self._args[idx] ++ except LookupError: ++ pass ++ key = str(idx) ++ return self._kwargs[key] ++ ++ def __iter__(self): ++ return iter(self._kwargs) ++ ++ def __len__(self): ++ return len(self._kwargs) ++ ++ ++def inspect_format_method(callable): ++ if not has_format: ++ return None ++ if not isinstance(callable, (types.MethodType, ++ types.BuiltinMethodType)) or \ ++ callable.__name__ != 'format': ++ return None ++ obj = callable.__self__ ++ if isinstance(obj, string_types): ++ return obj ++ + def safe_range(*args): + """A range that can't generate ranges with a length of more than + MAX_RANGE items. +@@ -139,6 +204,12 @@ def is_internal_attribute(obj, attr): + elif isinstance(obj, GeneratorType): + if attr == 'gi_frame': + return True ++ elif hasattr(types, 'CoroutineType') and isinstance(obj, types.CoroutineType): ++ if attr in UNSAFE_COROUTINE_ATTRIBUTES: ++ return True ++ elif hasattr(types, 'AsyncGeneratorType') and isinstance(obj, types.AsyncGeneratorType): ++ if attri in UNSAFE_ASYNC_GENERATOR_ATTRIBUTES: ++ return True + return attr.startswith('__') + + +@@ -177,8 +248,8 @@ class SandboxedEnvironment(Environment): + attributes or functions are safe to access. + + If the template tries to access insecure code a :exc:`SecurityError` is +- raised. However also other exceptions may occour during the rendering so +- the caller has to ensure that all exceptions are catched. ++ raised. However also other exceptions may occur during the rendering so ++ the caller has to ensure that all exceptions are caught. + """ + sandboxed = True + +@@ -340,8 +411,23 @@ class SandboxedEnvironment(Environment): + obj.__class__.__name__ + ), name=attribute, obj=obj, exc=SecurityError) + ++ def format_string(self, s, args, kwargs): ++ """If a format call is detected, then this is routed through this ++ method so that our safety sandbox can be used for it. ++ """ ++ if isinstance(s, Markup): ++ formatter = SandboxedEscapeFormatter(self, s.escape) ++ else: ++ formatter = SandboxedFormatter(self) ++ kwargs = _MagicFormatMapping(args, kwargs) ++ rv = formatter.vformat(s, args, kwargs) ++ return type(s)(rv) ++ + def call(__self, __context, __obj, *args, **kwargs): + """Call an object from sandboxed code.""" ++ fmt = inspect_format_method(__obj) ++ if fmt is not None: ++ return __self.format_string(fmt, args, kwargs) + # the double prefixes are to avoid double keyword argument + # errors when proxying the call. + if not __self.is_safe_callable(__obj): +@@ -359,3 +445,37 @@ class ImmutableSandboxedEnvironment(SandboxedEnvironment): + if not SandboxedEnvironment.is_safe_attribute(self, obj, attr, value): + return False + return not modifies_known_mutable(obj, attr) ++ ++ ++if has_format: ++ # This really is not a public API apparenlty. ++ try: ++ from _string import formatter_field_name_split ++ except ImportError: ++ def formatter_field_name_split(field_name): ++ return field_name._formatter_field_name_split() ++ ++ class SandboxedFormatterMixin(object): ++ ++ def __init__(self, env): ++ self._env = env ++ ++ def get_field(self, field_name, args, kwargs): ++ first, rest = formatter_field_name_split(field_name) ++ obj = self.get_value(first, args, kwargs) ++ for is_attr, i in rest: ++ if is_attr: ++ obj = self._env.getattr(obj, i) ++ else: ++ obj = self._env.getitem(obj, i) ++ return obj, first ++ ++ class SandboxedFormatter(SandboxedFormatterMixin, Formatter): ++ def __init__(self, env): ++ SandboxedFormatterMixin.__init__(self, env) ++ Formatter.__init__(self) ++ ++ class SandboxedEscapeFormatter(SandboxedFormatterMixin, EscapeFormatter): ++ def __init__(self, env, escape): ++ SandboxedFormatterMixin.__init__(self, env) ++ EscapeFormatter.__init__(self, escape) diff -Nru jinja2-2.6/debian/patches/CVE-2016-10745-2.patch jinja2-2.6/debian/patches/CVE-2016-10745-2.patch --- jinja2-2.6/debian/patches/CVE-2016-10745-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ jinja2-2.6/debian/patches/CVE-2016-10745-2.patch 2019-05-15 13:40:31.000000000 +0000 @@ -0,0 +1,20 @@ +Backport of: + +From 74bd64e56387f5b2931040dc7235a3509cde1611 Mon Sep 17 00:00:00 2001 +From: Armin Ronacher +Date: Thu, 29 Dec 2016 16:01:35 +0100 +Subject: [PATCH] Fixed a name error for an uncommon attribute access in the + sandbox +diff --git a/jinja2/sandbox.py b/jinja2/sandbox.py +index f80c714..437fb55 100644 +--- a/jinja2/sandbox.py ++++ b/jinja2/sandbox.py +@@ -208,7 +208,7 @@ def is_internal_attribute(obj, attr): + if attr in UNSAFE_COROUTINE_ATTRIBUTES: + return True + elif hasattr(types, 'AsyncGeneratorType') and isinstance(obj, types.AsyncGeneratorType): +- if attri in UNSAFE_ASYNC_GENERATOR_ATTRIBUTES: ++ if attr in UNSAFE_ASYNC_GENERATOR_ATTRIBUTES: + return True + return attr.startswith('__') + diff -Nru jinja2-2.6/debian/patches/CVE-2016-10745-3.patch jinja2-2.6/debian/patches/CVE-2016-10745-3.patch --- jinja2-2.6/debian/patches/CVE-2016-10745-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ jinja2-2.6/debian/patches/CVE-2016-10745-3.patch 2019-05-15 13:40:35.000000000 +0000 @@ -0,0 +1,44 @@ +From 54ab3b353efaa747712286374e212705979157f1 Mon Sep 17 00:00:00 2001 +From: "Leonidas S. Barbosa" +Date: Wed, 15 May 2019 08:42:49 -0300 +Subject: [PATCH] Backporting for CVE-2016-10745: adding EscapeFormatter class +diff --git a/jinja2/sandbox.py b/jinja2/sandbox.py +index 437fb55..d0bd274 100644 +--- a/jinja2/sandbox.py ++++ b/jinja2/sandbox.py +@@ -32,9 +32,34 @@ else: + + has_format = False + if hasattr(text_type, 'format'): +- from markupsafe import EscapeFormatter ++ # was removed from dependencies ++ #from markupsafe import EscapeFormatter + from string import Formatter + has_format = True ++ # Adding the whole class to fix CVE-2016-10745 ++ class EscapeFormatter(Formatter): ++ def __init__(self, escape): ++ self.escape = escape ++ ++ def format_field(self, value, format_spec): ++ if hasattr(value, "__html_format__"): ++ rv = value.__html_format__(format_spec) ++ elif hasattr(value, "__html__"): ++ if format_spec: ++ raise ValueError( ++ "Format specifier {0} given, but {1} does not" ++ " define __html_format__. A class that defines" ++ " __html__ must define __html_format__ to work" ++ " with format specifiers.".format(format_spec, type(value)) ++ ) ++ rv = value.__html__() ++ else: ++ # We need to make sure the format spec is unicode here as ++ # otherwise the wrong callback methods are invoked. For ++ # instance a byte string there would invoke __str__ and ++ # not __unicode__. ++ rv = Formatter.format_field(self, value, text_type(format_spec)) ++ return text_type(self.escape(rv)) + + #: maximum number of items a range may produce + MAX_RANGE = 100000 diff -Nru jinja2-2.6/debian/patches/CVE-2019-10906.patch jinja2-2.6/debian/patches/CVE-2019-10906.patch --- jinja2-2.6/debian/patches/CVE-2019-10906.patch 1970-01-01 00:00:00.000000000 +0000 +++ jinja2-2.6/debian/patches/CVE-2019-10906.patch 2019-05-15 13:40:47.000000000 +0000 @@ -0,0 +1,56 @@ + +Backport of: + +From a2a6c930bcca591a25d2b316fcfd2d6793897b26 Mon Sep 17 00:00:00 2001 +From: Armin Ronacher +Date: Sat, 6 Apr 2019 10:50:47 -0700 +Subject: [PATCH] sandbox str.format_map +Index: jinja2-2.6/jinja2/sandbox.py +=================================================================== +--- jinja2-2.6.orig/jinja2/sandbox.py ++++ jinja2-2.6/jinja2/sandbox.py +@@ -170,7 +170,7 @@ def inspect_format_method(callable): + return None + if not isinstance(callable, (types.MethodType, + types.BuiltinMethodType)) or \ +- callable.__name__ != 'format': ++ callable.__name__ not in ('format', 'format_map'): + return None + obj = callable.__self__ + if isinstance(obj, string_types): +@@ -436,7 +436,7 @@ class SandboxedEnvironment(Environment): + obj.__class__.__name__ + ), name=attribute, obj=obj, exc=SecurityError) + +- def format_string(self, s, args, kwargs): ++ def format_string(self, s, args, kwargs, format_func=None): + """If a format call is detected, then this is routed through this + method so that our safety sandbox can be used for it. + """ +@@ -444,6 +444,17 @@ class SandboxedEnvironment(Environment): + formatter = SandboxedEscapeFormatter(self, s.escape) + else: + formatter = SandboxedFormatter(self) ++ ++ if format_func is not None and format_func.__name__ == 'format_map': ++ if len(args) != 1 or kwargs: ++ raise TypeError( ++ 'format_map() takes exactly one argument %d given' ++ % (len(args) + (kwargs is not None)) ++ ) ++ ++ kwargs = args[0] ++ args = None ++ + kwargs = _MagicFormatMapping(args, kwargs) + rv = formatter.vformat(s, args, kwargs) + return type(s)(rv) +@@ -452,7 +463,7 @@ class SandboxedEnvironment(Environment): + """Call an object from sandboxed code.""" + fmt = inspect_format_method(__obj) + if fmt is not None: +- return __self.format_string(fmt, args, kwargs) ++ return __self.format_string(fmt, args, kwargs, __obj) + # the double prefixes are to avoid double keyword argument + # errors when proxying the call. + if not __self.is_safe_callable(__obj): diff -Nru jinja2-2.6/debian/patches/series jinja2-2.6/debian/patches/series --- jinja2-2.6/debian/patches/series 2014-07-22 15:10:11.000000000 +0000 +++ jinja2-2.6/debian/patches/series 2019-05-15 13:40:43.000000000 +0000 @@ -1,2 +1,6 @@ CVE-2014-1402.patch CVE-2014-0012.patch +CVE-2016-10745-1.patch +CVE-2016-10745-2.patch +CVE-2016-10745-3.patch +CVE-2019-10906.patch