blob: 5974e1f6813108972ed499828e6012ba8d6086a0 [file] [log] [blame]
Armin Ronacherccf284b2007-05-21 16:44:26 +02001# -*- coding: utf-8 -*-
2"""
3 unit test for security features
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 :copyright: 2007 by Armin Ronacher.
7 :license: BSD, see LICENSE for more details.
8"""
Armin Ronacher6df604e2008-05-23 22:18:38 +02009from jinja2.sandbox import SandboxedEnvironment, \
10 ImmutableSandboxedEnvironment, unsafe
Armin Ronacherccf284b2007-05-21 16:44:26 +020011
12
13class PrivateStuff(object):
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020014
15 def bar(self):
16 return 23
17
18 @unsafe
19 def foo(self):
20 return 42
21
22 def __repr__(self):
23 return 'PrivateStuff'
Armin Ronacherccf284b2007-05-21 16:44:26 +020024
25
26class PublicStuff(object):
Armin Ronacherccf284b2007-05-21 16:44:26 +020027 bar = lambda self: 23
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020028 _foo = lambda self: 42
29
30 def __repr__(self):
31 return 'PublicStuff'
Armin Ronacherccf284b2007-05-21 16:44:26 +020032
33
34test_unsafe = '''
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020035>>> env = MODULE.SandboxedEnvironment()
Armin Ronacherccf284b2007-05-21 16:44:26 +020036>>> env.from_string("{{ foo.foo() }}").render(foo=MODULE.PrivateStuff())
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020037Traceback (most recent call last):
38 ...
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020039SecurityError: <bound method PrivateStuff.foo of PrivateStuff> is not safely callable
Armin Ronacherccf284b2007-05-21 16:44:26 +020040>>> env.from_string("{{ foo.bar() }}").render(foo=MODULE.PrivateStuff())
41u'23'
42
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020043>>> env.from_string("{{ foo._foo() }}").render(foo=MODULE.PublicStuff())
44Traceback (most recent call last):
45 ...
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020046SecurityError: access to attribute '_foo' of 'PublicStuff' object is unsafe.
Armin Ronacherccf284b2007-05-21 16:44:26 +020047>>> env.from_string("{{ foo.bar() }}").render(foo=MODULE.PublicStuff())
48u'23'
49
50>>> env.from_string("{{ foo.__class__ }}").render(foo=42)
51u''
Armin Ronacherccf284b2007-05-21 16:44:26 +020052>>> env.from_string("{{ foo.func_code }}").render(foo=lambda:None)
53u''
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020054>>> env.from_string("{{ foo.__class__.__subclasses__() }}").render(foo=42)
55Traceback (most recent call last):
56 ...
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020057SecurityError: access to attribute '__class__' of 'int' object is unsafe.
Armin Ronacherccf284b2007-05-21 16:44:26 +020058'''
59
60
61test_restricted = '''
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020062>>> env = MODULE.SandboxedEnvironment()
Armin Ronacherccf284b2007-05-21 16:44:26 +020063>>> env.from_string("{% for item.attribute in seq %}...{% endfor %}")
64Traceback (most recent call last):
65 ...
Armin Ronacher09c002e2008-05-10 22:21:30 +020066TemplateSyntaxError: expected token 'in', got '.' (line 1)
Armin Ronacherecc051b2007-06-01 18:25:28 +020067>>> env.from_string("{% for foo, bar.baz in seq %}...{% endfor %}")
68Traceback (most recent call last):
69 ...
Armin Ronacher09c002e2008-05-10 22:21:30 +020070TemplateSyntaxError: expected token 'in', got '.' (line 1)
Armin Ronacherccf284b2007-05-21 16:44:26 +020071'''
Armin Ronacher6df604e2008-05-23 22:18:38 +020072
73
74test_immutable_environment = '''
75>>> env = MODULE.ImmutableSandboxedEnvironment()
76>>> env.from_string('{{ [].append(23) }}').render()
77Traceback (most recent call last):
78 ...
79SecurityError: access to attribute 'append' of 'list' object is unsafe.
80>>> env.from_string('{{ {1:2}.clear() }}').render()
81Traceback (most recent call last):
82 ...
83SecurityError: access to attribute 'clear' of 'dict' object is unsafe.
84'''