| OLD | NEW |
| 1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
| 2 """ | 2 """ |
| 3 jinja2.sandbox | 3 jinja2.sandbox |
| 4 ~~~~~~~~~~~~~~ | 4 ~~~~~~~~~~~~~~ |
| 5 | 5 |
| 6 Adds a sandbox layer to Jinja as it was the default behavior in the old | 6 Adds a sandbox layer to Jinja as it was the default behavior in the old |
| 7 Jinja 1 releases. This sandbox is slightly different from Jinja 1 as the | 7 Jinja 1 releases. This sandbox is slightly different from Jinja 1 as the |
| 8 default behavior is easier to use. | 8 default behavior is easier to use. |
| 9 | 9 |
| 10 The behavior can be changed by subclassing the environment. | 10 The behavior can be changed by subclassing the environment. |
| 11 | 11 |
| 12 :copyright: (c) 2010 by the Jinja Team. | 12 :copyright: (c) 2010 by the Jinja Team. |
| 13 :license: BSD. | 13 :license: BSD. |
| 14 """ | 14 """ |
| 15 import types |
| 15 import operator | 16 import operator |
| 16 from jinja2.environment import Environment | 17 from jinja2.environment import Environment |
| 17 from jinja2.exceptions import SecurityError | 18 from jinja2.exceptions import SecurityError |
| 18 from jinja2._compat import string_types, function_type, method_type, \ | 19 from jinja2._compat import string_types, PY2 |
| 19 traceback_type, code_type, frame_type, generator_type, PY2 | |
| 20 | 20 |
| 21 | 21 |
| 22 #: maximum number of items a range may produce | 22 #: maximum number of items a range may produce |
| 23 MAX_RANGE = 100000 | 23 MAX_RANGE = 100000 |
| 24 | 24 |
| 25 #: attributes of function objects that are considered unsafe. | 25 #: attributes of function objects that are considered unsafe. |
| 26 UNSAFE_FUNCTION_ATTRIBUTES = set(['func_closure', 'func_code', 'func_dict', | 26 if PY2: |
| 27 'func_defaults', 'func_globals']) | 27 UNSAFE_FUNCTION_ATTRIBUTES = set(['func_closure', 'func_code', 'func_dict', |
| 28 'func_defaults', 'func_globals']) |
| 29 else: |
| 30 # On versions > python 2 the special attributes on functions are gone, |
| 31 # but they remain on methods and generators for whatever reason. |
| 32 UNSAFE_FUNCTION_ATTRIBUTES = set() |
| 33 |
| 28 | 34 |
| 29 #: unsafe method attributes. function attributes are unsafe for methods too | 35 #: unsafe method attributes. function attributes are unsafe for methods too |
| 30 UNSAFE_METHOD_ATTRIBUTES = set(['im_class', 'im_func', 'im_self']) | 36 UNSAFE_METHOD_ATTRIBUTES = set(['im_class', 'im_func', 'im_self']) |
| 31 | 37 |
| 32 #: unsafe generator attirbutes. | 38 #: unsafe generator attirbutes. |
| 33 UNSAFE_GENERATOR_ATTRIBUTES = set(['gi_frame', 'gi_code']) | 39 UNSAFE_GENERATOR_ATTRIBUTES = set(['gi_frame', 'gi_code']) |
| 34 | 40 |
| 35 # On versions > python 2 the special attributes on functions are gone, | |
| 36 # but they remain on methods and generators for whatever reason. | |
| 37 if not PY2: | |
| 38 UNSAFE_FUNCTION_ATTRIBUTES = set() | |
| 39 | |
| 40 import warnings | 41 import warnings |
| 41 | 42 |
| 42 # make sure we don't warn in python 2.6 about stuff we don't care about | 43 # make sure we don't warn in python 2.6 about stuff we don't care about |
| 43 warnings.filterwarnings('ignore', 'the sets module', DeprecationWarning, | 44 warnings.filterwarnings('ignore', 'the sets module', DeprecationWarning, |
| 44 module='jinja2.sandbox') | 45 module='jinja2.sandbox') |
| 45 | 46 |
| 46 from collections import deque | 47 from collections import deque |
| 47 | 48 |
| 48 _mutable_set_types = (set,) | 49 _mutable_set_types = (set,) |
| 49 _mutable_mapping_types = (dict,) | 50 _mutable_mapping_types = (dict,) |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 return f | 118 return f |
| 118 | 119 |
| 119 | 120 |
| 120 def is_internal_attribute(obj, attr): | 121 def is_internal_attribute(obj, attr): |
| 121 """Test if the attribute given is an internal python attribute. For | 122 """Test if the attribute given is an internal python attribute. For |
| 122 example this function returns `True` for the `func_code` attribute of | 123 example this function returns `True` for the `func_code` attribute of |
| 123 python objects. This is useful if the environment method | 124 python objects. This is useful if the environment method |
| 124 :meth:`~SandboxedEnvironment.is_safe_attribute` is overridden. | 125 :meth:`~SandboxedEnvironment.is_safe_attribute` is overridden. |
| 125 | 126 |
| 126 >>> from jinja2.sandbox import is_internal_attribute | 127 >>> from jinja2.sandbox import is_internal_attribute |
| 127 >>> is_internal_attribute(lambda: None, "func_code") | 128 >>> is_internal_attribute(str, "mro") |
| 128 True | |
| 129 >>> is_internal_attribute((lambda x:x).func_code, 'co_code') | |
| 130 True | 129 True |
| 131 >>> is_internal_attribute(str, "upper") | 130 >>> is_internal_attribute(str, "upper") |
| 132 False | 131 False |
| 133 """ | 132 """ |
| 134 if isinstance(obj, function_type): | 133 if isinstance(obj, types.FunctionType): |
| 135 if attr in UNSAFE_FUNCTION_ATTRIBUTES: | 134 if attr in UNSAFE_FUNCTION_ATTRIBUTES: |
| 136 return True | 135 return True |
| 137 elif isinstance(obj, method_type): | 136 elif isinstance(obj, types.MethodType): |
| 138 if attr in UNSAFE_FUNCTION_ATTRIBUTES or \ | 137 if attr in UNSAFE_FUNCTION_ATTRIBUTES or \ |
| 139 attr in UNSAFE_METHOD_ATTRIBUTES: | 138 attr in UNSAFE_METHOD_ATTRIBUTES: |
| 140 return True | 139 return True |
| 141 elif isinstance(obj, type): | 140 elif isinstance(obj, type): |
| 142 if attr == 'mro': | 141 if attr == 'mro': |
| 143 return True | 142 return True |
| 144 elif isinstance(obj, (code_type, traceback_type, frame_type)): | 143 elif isinstance(obj, (types.CodeType, types.TracebackType, types.FrameType))
: |
| 145 return True | 144 return True |
| 146 elif isinstance(obj, generator_type): | 145 elif isinstance(obj, types.GeneratorType): |
| 147 if attr in UNSAFE_GENERATOR_ATTRIBUTES: | 146 if attr in UNSAFE_GENERATOR_ATTRIBUTES: |
| 148 return True | 147 return True |
| 149 return attr.startswith('__') | 148 return attr.startswith('__') |
| 150 | 149 |
| 151 | 150 |
| 152 def modifies_known_mutable(obj, attr): | 151 def modifies_known_mutable(obj, attr): |
| 153 """This function checks if an attribute on a builtin mutable object | 152 """This function checks if an attribute on a builtin mutable object |
| 154 (list, dict, set or deque) would modify it if called. It also supports | 153 (list, dict, set or deque) would modify it if called. It also supports |
| 155 the "user"-versions of the objects (`sets.Set`, `UserDict.*` etc.) and | 154 the "user"-versions of the objects (`sets.Set`, `UserDict.*` etc.) and |
| 156 with Python 2.6 onwards the abstract base classes `MutableSet`, | 155 with Python 2.6 onwards the abstract base classes `MutableSet`, |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 class ImmutableSandboxedEnvironment(SandboxedEnvironment): | 358 class ImmutableSandboxedEnvironment(SandboxedEnvironment): |
| 360 """Works exactly like the regular `SandboxedEnvironment` but does not | 359 """Works exactly like the regular `SandboxedEnvironment` but does not |
| 361 permit modifications on the builtin mutable objects `list`, `set`, and | 360 permit modifications on the builtin mutable objects `list`, `set`, and |
| 362 `dict` by using the :func:`modifies_known_mutable` function. | 361 `dict` by using the :func:`modifies_known_mutable` function. |
| 363 """ | 362 """ |
| 364 | 363 |
| 365 def is_safe_attribute(self, obj, attr, value): | 364 def is_safe_attribute(self, obj, attr, value): |
| 366 if not SandboxedEnvironment.is_safe_attribute(self, obj, attr, value): | 365 if not SandboxedEnvironment.is_safe_attribute(self, obj, attr, value): |
| 367 return False | 366 return False |
| 368 return not modifies_known_mutable(obj, attr) | 367 return not modifies_known_mutable(obj, attr) |
| OLD | NEW |