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 |