blob: 6813656fd856c15d5725e5ceb5cdc09642de134b [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 Ronacher4f7d2d52008-04-22 10:40:26 +02009from jinja2.sandbox import SandboxedEnvironment, unsafe
Armin Ronacherccf284b2007-05-21 16:44:26 +020010
11
12class PrivateStuff(object):
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020013
14 def bar(self):
15 return 23
16
17 @unsafe
18 def foo(self):
19 return 42
20
21 def __repr__(self):
22 return 'PrivateStuff'
Armin Ronacherccf284b2007-05-21 16:44:26 +020023
24
25class PublicStuff(object):
Armin Ronacherccf284b2007-05-21 16:44:26 +020026 bar = lambda self: 23
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020027 _foo = lambda self: 42
28
29 def __repr__(self):
30 return 'PublicStuff'
Armin Ronacherccf284b2007-05-21 16:44:26 +020031
32
33test_unsafe = '''
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020034>>> env = MODULE.SandboxedEnvironment()
Armin Ronacherccf284b2007-05-21 16:44:26 +020035>>> env.from_string("{{ foo.foo() }}").render(foo=MODULE.PrivateStuff())
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020036Traceback (most recent call last):
37 ...
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020038SecurityError: <bound method PrivateStuff.foo of PrivateStuff> is not safely callable
Armin Ronacherccf284b2007-05-21 16:44:26 +020039>>> env.from_string("{{ foo.bar() }}").render(foo=MODULE.PrivateStuff())
40u'23'
41
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020042>>> env.from_string("{{ foo._foo() }}").render(foo=MODULE.PublicStuff())
43Traceback (most recent call last):
44 ...
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020045SecurityError: access to attribute '_foo' of 'PublicStuff' object is unsafe.
Armin Ronacherccf284b2007-05-21 16:44:26 +020046>>> env.from_string("{{ foo.bar() }}").render(foo=MODULE.PublicStuff())
47u'23'
48
49>>> env.from_string("{{ foo.__class__ }}").render(foo=42)
50u''
Armin Ronacherccf284b2007-05-21 16:44:26 +020051>>> env.from_string("{{ foo.func_code }}").render(foo=lambda:None)
52u''
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020053>>> env.from_string("{{ foo.__class__.__subclasses__() }}").render(foo=42)
54Traceback (most recent call last):
55 ...
Armin Ronacher5cdc1ac2008-05-07 12:17:18 +020056SecurityError: access to attribute '__class__' of 'int' object is unsafe.
Armin Ronacherccf284b2007-05-21 16:44:26 +020057'''
58
59
60test_restricted = '''
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020061>>> env = MODULE.SandboxedEnvironment()
Armin Ronacherccf284b2007-05-21 16:44:26 +020062>>> env.from_string("{% for item.attribute in seq %}...{% endfor %}")
63Traceback (most recent call last):
64 ...
Armin Ronacher09c002e2008-05-10 22:21:30 +020065TemplateSyntaxError: expected token 'in', got '.' (line 1)
Armin Ronacherecc051b2007-06-01 18:25:28 +020066>>> env.from_string("{% for foo, bar.baz in seq %}...{% endfor %}")
67Traceback (most recent call last):
68 ...
Armin Ronacher09c002e2008-05-10 22:21:30 +020069TemplateSyntaxError: expected token 'in', got '.' (line 1)
Armin Ronacherccf284b2007-05-21 16:44:26 +020070'''