PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/helloflask/venv/lib/python2.6/site-packages/jinja2/sandbox.py

https://bitbucket.org/ksetyadi/helloworld
Python | 361 lines | 320 code | 16 blank | 25 comment | 8 complexity | 75e757c1420d6f0d32ef25e503440ac6 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. """
  3. jinja2.sandbox
  4. ~~~~~~~~~~~~~~
  5. Adds a sandbox layer to Jinja as it was the default behavior in the old
  6. Jinja 1 releases. This sandbox is slightly different from Jinja 1 as the
  7. default behavior is easier to use.
  8. The behavior can be changed by subclassing the environment.
  9. :copyright: (c) 2010 by the Jinja Team.
  10. :license: BSD.
  11. """
  12. import operator
  13. from jinja2.environment import Environment
  14. from jinja2.exceptions import SecurityError
  15. from jinja2.utils import FunctionType, MethodType, TracebackType, CodeType, \
  16. FrameType, GeneratorType
  17. #: maximum number of items a range may produce
  18. MAX_RANGE = 100000
  19. #: attributes of function objects that are considered unsafe.
  20. UNSAFE_FUNCTION_ATTRIBUTES = set(['func_closure', 'func_code', 'func_dict',
  21. 'func_defaults', 'func_globals'])
  22. #: unsafe method attributes. function attributes are unsafe for methods too
  23. UNSAFE_METHOD_ATTRIBUTES = set(['im_class', 'im_func', 'im_self'])
  24. import warnings
  25. # make sure we don't warn in python 2.6 about stuff we don't care about
  26. warnings.filterwarnings('ignore', 'the sets module', DeprecationWarning,
  27. module='jinja2.sandbox')
  28. from collections import deque
  29. _mutable_set_types = (set,)
  30. _mutable_mapping_types = (dict,)
  31. _mutable_sequence_types = (list,)
  32. # on python 2.x we can register the user collection types
  33. try:
  34. from UserDict import UserDict, DictMixin
  35. from UserList import UserList
  36. _mutable_mapping_types += (UserDict, DictMixin)
  37. _mutable_set_types += (UserList,)
  38. except ImportError:
  39. pass
  40. # if sets is still available, register the mutable set from there as well
  41. try:
  42. from sets import Set
  43. _mutable_set_types += (Set,)
  44. except ImportError:
  45. pass
  46. #: register Python 2.6 abstract base classes
  47. try:
  48. from collections import MutableSet, MutableMapping, MutableSequence
  49. _mutable_set_types += (MutableSet,)
  50. _mutable_mapping_types += (MutableMapping,)
  51. _mutable_sequence_types += (MutableSequence,)
  52. except ImportError:
  53. pass
  54. _mutable_spec = (
  55. (_mutable_set_types, frozenset([
  56. 'add', 'clear', 'difference_update', 'discard', 'pop', 'remove',
  57. 'symmetric_difference_update', 'update'
  58. ])),
  59. (_mutable_mapping_types, frozenset([
  60. 'clear', 'pop', 'popitem', 'setdefault', 'update'
  61. ])),
  62. (_mutable_sequence_types, frozenset([
  63. 'append', 'reverse', 'insert', 'sort', 'extend', 'remove'
  64. ])),
  65. (deque, frozenset([
  66. 'append', 'appendleft', 'clear', 'extend', 'extendleft', 'pop',
  67. 'popleft', 'remove', 'rotate'
  68. ]))
  69. )
  70. def safe_range(*args):
  71. """A range that can't generate ranges with a length of more than
  72. MAX_RANGE items.
  73. """
  74. rng = xrange(*args)
  75. if len(rng) > MAX_RANGE:
  76. raise OverflowError('range too big, maximum size for range is %d' %
  77. MAX_RANGE)
  78. return rng
  79. def unsafe(f):
  80. """Marks a function or method as unsafe.
  81. ::
  82. @unsafe
  83. def delete(self):
  84. pass
  85. """
  86. f.unsafe_callable = True
  87. return f
  88. def is_internal_attribute(obj, attr):
  89. """Test if the attribute given is an internal python attribute. For
  90. example this function returns `True` for the `func_code` attribute of
  91. python objects. This is useful if the environment method
  92. :meth:`~SandboxedEnvironment.is_safe_attribute` is overriden.
  93. >>> from jinja2.sandbox import is_internal_attribute
  94. >>> is_internal_attribute(lambda: None, "func_code")
  95. True
  96. >>> is_internal_attribute((lambda x:x).func_code, 'co_code')
  97. True
  98. >>> is_internal_attribute(str, "upper")
  99. False
  100. """
  101. if isinstance(obj, FunctionType):
  102. if attr in UNSAFE_FUNCTION_ATTRIBUTES:
  103. return True
  104. elif isinstance(obj, MethodType):
  105. if attr in UNSAFE_FUNCTION_ATTRIBUTES or \
  106. attr in UNSAFE_METHOD_ATTRIBUTES:
  107. return True
  108. elif isinstance(obj, type):
  109. if attr == 'mro':
  110. return True
  111. elif isinstance(obj, (CodeType, TracebackType, FrameType)):
  112. return True
  113. elif isinstance(obj, GeneratorType):
  114. if attr == 'gi_frame':
  115. return True
  116. return attr.startswith('__')
  117. def modifies_known_mutable(obj, attr):
  118. """This function checks if an attribute on a builtin mutable object
  119. (list, dict, set or deque) would modify it if called. It also supports
  120. the "user"-versions of the objects (`sets.Set`, `UserDict.*` etc.) and
  121. with Python 2.6 onwards the abstract base classes `MutableSet`,
  122. `MutableMapping`, and `MutableSequence`.
  123. >>> modifies_known_mutable({}, "clear")
  124. True
  125. >>> modifies_known_mutable({}, "keys")
  126. False
  127. >>> modifies_known_mutable([], "append")
  128. True
  129. >>> modifies_known_mutable([], "index")
  130. False
  131. If called with an unsupported object (such as unicode) `False` is
  132. returned.
  133. >>> modifies_known_mutable("foo", "upper")
  134. False
  135. """
  136. for typespec, unsafe in _mutable_spec:
  137. if isinstance(obj, typespec):
  138. return attr in unsafe
  139. return False
  140. class SandboxedEnvironment(Environment):
  141. """The sandboxed environment. It works like the regular environment but
  142. tells the compiler to generate sandboxed code. Additionally subclasses of
  143. this environment may override the methods that tell the runtime what
  144. attributes or functions are safe to access.
  145. If the template tries to access insecure code a :exc:`SecurityError` is
  146. raised. However also other exceptions may occour during the rendering so
  147. the caller has to ensure that all exceptions are catched.
  148. """
  149. sandboxed = True
  150. #: default callback table for the binary operators. A copy of this is
  151. #: available on each instance of a sandboxed environment as
  152. #: :attr:`binop_table`
  153. default_binop_table = {
  154. '+': operator.add,
  155. '-': operator.sub,
  156. '*': operator.mul,
  157. '/': operator.truediv,
  158. '//': operator.floordiv,
  159. '**': operator.pow,
  160. '%': operator.mod
  161. }
  162. #: default callback table for the unary operators. A copy of this is
  163. #: available on each instance of a sandboxed environment as
  164. #: :attr:`unop_table`
  165. default_unop_table = {
  166. '+': operator.pos,
  167. '-': operator.neg
  168. }
  169. #: a set of binary operators that should be intercepted. Each operator
  170. #: that is added to this set (empty by default) is delegated to the
  171. #: :meth:`call_binop` method that will perform the operator. The default
  172. #: operator callback is specified by :attr:`binop_table`.
  173. #:
  174. #: The following binary operators are interceptable:
  175. #: ``//``, ``%``, ``+``, ``*``, ``-``, ``/``, and ``**``
  176. #:
  177. #: The default operation form the operator table corresponds to the
  178. #: builtin function. Intercepted calls are always slower than the native
  179. #: operator call, so make sure only to intercept the ones you are
  180. #: interested in.
  181. #:
  182. #: .. versionadded:: 2.6
  183. intercepted_binops = frozenset()
  184. #: a set of unary operators that should be intercepted. Each operator
  185. #: that is added to this set (empty by default) is delegated to the
  186. #: :meth:`call_unop` method that will perform the operator. The default
  187. #: operator callback is specified by :attr:`unop_table`.
  188. #:
  189. #: The following unary operators are interceptable: ``+``, ``-``
  190. #:
  191. #: The default operation form the operator table corresponds to the
  192. #: builtin function. Intercepted calls are always slower than the native
  193. #: operator call, so make sure only to intercept the ones you are
  194. #: interested in.
  195. #:
  196. #: .. versionadded:: 2.6
  197. intercepted_unops = frozenset()
  198. def intercept_unop(self, operator):
  199. """Called during template compilation with the name of a unary
  200. operator to check if it should be intercepted at runtime. If this
  201. method returns `True`, :meth:`call_unop` is excuted for this unary
  202. operator. The default implementation of :meth:`call_unop` will use
  203. the :attr:`unop_table` dictionary to perform the operator with the
  204. same logic as the builtin one.
  205. The following unary operators are interceptable: ``+`` and ``-``
  206. Intercepted calls are always slower than the native operator call,
  207. so make sure only to intercept the ones you are interested in.
  208. .. versionadded:: 2.6
  209. """
  210. return False
  211. def __init__(self, *args, **kwargs):
  212. Environment.__init__(self, *args, **kwargs)
  213. self.globals['range'] = safe_range
  214. self.binop_table = self.default_binop_table.copy()
  215. self.unop_table = self.default_unop_table.copy()
  216. def is_safe_attribute(self, obj, attr, value):
  217. """The sandboxed environment will call this method to check if the
  218. attribute of an object is safe to access. Per default all attributes
  219. starting with an underscore are considered private as well as the
  220. special attributes of internal python objects as returned by the
  221. :func:`is_internal_attribute` function.
  222. """
  223. return not (attr.startswith('_') or is_internal_attribute(obj, attr))
  224. def is_safe_callable(self, obj):
  225. """Check if an object is safely callable. Per default a function is
  226. considered safe unless the `unsafe_callable` attribute exists and is
  227. True. Override this method to alter the behavior, but this won't
  228. affect the `unsafe` decorator from this module.
  229. """
  230. return not (getattr(obj, 'unsafe_callable', False) or
  231. getattr(obj, 'alters_data', False))
  232. def call_binop(self, context, operator, left, right):
  233. """For intercepted binary operator calls (:meth:`intercepted_binops`)
  234. this function is executed instead of the builtin operator. This can
  235. be used to fine tune the behavior of certain operators.
  236. .. versionadded:: 2.6
  237. """
  238. return self.binop_table[operator](left, right)
  239. def call_unop(self, context, operator, arg):
  240. """For intercepted unary operator calls (:meth:`intercepted_unops`)
  241. this function is executed instead of the builtin operator. This can
  242. be used to fine tune the behavior of certain operators.
  243. .. versionadded:: 2.6
  244. """
  245. return self.unop_table[operator](arg)
  246. def getitem(self, obj, argument):
  247. """Subscribe an object from sandboxed code."""
  248. try:
  249. return obj[argument]
  250. except (TypeError, LookupError):
  251. if isinstance(argument, basestring):
  252. try:
  253. attr = str(argument)
  254. except Exception:
  255. pass
  256. else:
  257. try:
  258. value = getattr(obj, attr)
  259. except AttributeError:
  260. pass
  261. else:
  262. if self.is_safe_attribute(obj, argument, value):
  263. return value
  264. return self.unsafe_undefined(obj, argument)
  265. return self.undefined(obj=obj, name=argument)
  266. def getattr(self, obj, attribute):
  267. """Subscribe an object from sandboxed code and prefer the
  268. attribute. The attribute passed *must* be a bytestring.
  269. """
  270. try:
  271. value = getattr(obj, attribute)
  272. except AttributeError:
  273. try:
  274. return obj[attribute]
  275. except (TypeError, LookupError):
  276. pass
  277. else:
  278. if self.is_safe_attribute(obj, attribute, value):
  279. return value
  280. return self.unsafe_undefined(obj, attribute)
  281. return self.undefined(obj=obj, name=attribute)
  282. def unsafe_undefined(self, obj, attribute):
  283. """Return an undefined object for unsafe attributes."""
  284. return self.undefined('access to attribute %r of %r '
  285. 'object is unsafe.' % (
  286. attribute,
  287. obj.__class__.__name__
  288. ), name=attribute, obj=obj, exc=SecurityError)
  289. def call(__self, __context, __obj, *args, **kwargs):
  290. """Call an object from sandboxed code."""
  291. # the double prefixes are to avoid double keyword argument
  292. # errors when proxying the call.
  293. if not __self.is_safe_callable(__obj):
  294. raise SecurityError('%r is not safely callable' % (__obj,))
  295. return __context.call(__obj, *args, **kwargs)
  296. class ImmutableSandboxedEnvironment(SandboxedEnvironment):
  297. """Works exactly like the regular `SandboxedEnvironment` but does not
  298. permit modifications on the builtin mutable objects `list`, `set`, and
  299. `dict` by using the :func:`modifies_known_mutable` function.
  300. """
  301. def is_safe_attribute(self, obj, attr, value):
  302. if not SandboxedEnvironment.is_safe_attribute(self, obj, attr, value):
  303. return False
  304. return not modifies_known_mutable(obj, attr)