diff options
Diffstat (limited to 'docs/sandbox.rst')
-rw-r--r-- | docs/sandbox.rst | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/docs/sandbox.rst b/docs/sandbox.rst new file mode 100644 index 00000000..1222d025 --- /dev/null +++ b/docs/sandbox.rst @@ -0,0 +1,94 @@ +Sandbox +======= + +The Jinja sandbox can be used to evaluate untrusted code. Access to unsafe +attributes and methods is prohibited. + +Assuming `env` is a :class:`SandboxedEnvironment` in the default configuration +the following piece of code shows how it works: + +>>> env.from_string("{{ func.func_code }}").render(func=lambda:None) +u'' +>>> env.from_string("{{ func.func_code.do_something }}").render(func=lambda:None) +Traceback (most recent call last): + ... +SecurityError: access to attribute 'func_code' of 'function' object is unsafe. + +API +--- + +.. module:: jinja2.sandbox + +.. autoclass:: SandboxedEnvironment([options]) + :members: is_safe_attribute, is_safe_callable, default_binop_table, + default_unop_table, intercepted_binops, intercepted_unops, + call_binop, call_unop + +.. autoclass:: ImmutableSandboxedEnvironment([options]) + +.. autoexception:: SecurityError + +.. autofunction:: unsafe + +.. autofunction:: is_internal_attribute + +.. autofunction:: modifies_known_mutable + +.. admonition:: Note + + The Jinja sandbox alone is no solution for perfect security. Especially + for web applications you have to keep in mind that users may create + templates with arbitrary HTML in so it's crucial to ensure that (if you + are running multiple users on the same server) they can't harm each other + via JavaScript insertions and much more. + + Also the sandbox is only as good as the configuration. We strongly + recommend only passing non-shared resources to the template and use + some sort of whitelisting for attributes. + + Also keep in mind that templates may raise runtime or compile time errors, + so make sure to catch them. + +Operator Intercepting +--------------------- + +.. versionadded:: 2.6 + +For maximum performance Jinja will let operators call directly the type +specific callback methods. This means that it's not possible to have this +intercepted by overriding :meth:`Environment.call`. Furthermore a +conversion from operator to special method is not always directly possible +due to how operators work. For instance for divisions more than one +special method exist. + +With Jinja 2.6 there is now support for explicit operator intercepting. +This can be used to customize specific operators as necessary. In order +to intercept an operator one has to override the +:attr:`SandboxedEnvironment.intercepted_binops` attribute. Once the +operator that needs to be intercepted is added to that set Jinja will +generate bytecode that calls the :meth:`SandboxedEnvironment.call_binop` +function. For unary operators the `unary` attributes and methods have to +be used instead. + +The default implementation of :attr:`SandboxedEnvironment.call_binop` +will use the :attr:`SandboxedEnvironment.binop_table` to translate +operator symbols into callbacks performing the default operator behavior. + +This example shows how the power (``**``) operator can be disabled in +Jinja:: + + from jinja2.sandbox import SandboxedEnvironment + + + class MyEnvironment(SandboxedEnvironment): + intercepted_binops = frozenset(['**']) + + def call_binop(self, context, operator, left, right): + if operator == '**': + return self.undefined('the power operator is unavailable') + return SandboxedEnvironment.call_binop(self, context, + operator, left, right) + +Make sure to always call into the super method, even if you are not +intercepting the call. Jinja might internally call the method to +evaluate expressions. |