security.py (4376B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\testsuite\security.py 2 import unittest 3 from jinja2.testsuite import JinjaTestCase 4 from jinja2 import Environment 5 from jinja2.sandbox import SandboxedEnvironment, ImmutableSandboxedEnvironment, unsafe 6 from jinja2 import Markup, escape 7 from jinja2.exceptions import SecurityError, TemplateSyntaxError, TemplateRuntimeError 8 9 class PrivateStuff(object): 10 11 def bar(self): 12 return 23 13 14 @unsafe 15 def foo(self): 16 return 42 17 18 def __repr__(self): 19 return 'PrivateStuff' 20 21 22 class PublicStuff(object): 23 bar = lambda self: 23 24 _foo = lambda self: 42 25 26 def __repr__(self): 27 return 'PublicStuff' 28 29 30 class SandboxTestCase(JinjaTestCase): 31 32 def test_unsafe(self): 33 env = SandboxedEnvironment() 34 self.assert_raises(SecurityError, env.from_string('{{ foo.foo() }}').render, foo=PrivateStuff()) 35 self.assert_equal(env.from_string('{{ foo.bar() }}').render(foo=PrivateStuff()), '23') 36 self.assert_raises(SecurityError, env.from_string('{{ foo._foo() }}').render, foo=PublicStuff()) 37 self.assert_equal(env.from_string('{{ foo.bar() }}').render(foo=PublicStuff()), '23') 38 self.assert_equal(env.from_string('{{ foo.__class__ }}').render(foo=42), '') 39 self.assert_equal(env.from_string('{{ foo.func_code }}').render(foo=lambda : None), '') 40 self.assert_raises(SecurityError, env.from_string('{{ foo.__class__.__subclasses__() }}').render, foo=42) 41 42 def test_immutable_environment(self): 43 env = ImmutableSandboxedEnvironment() 44 self.assert_raises(SecurityError, env.from_string('{{ [].append(23) }}').render) 45 self.assert_raises(SecurityError, env.from_string('{{ {1:2}.clear() }}').render) 46 47 def test_restricted(self): 48 env = SandboxedEnvironment() 49 self.assert_raises(TemplateSyntaxError, env.from_string, '{% for item.attribute in seq %}...{% endfor %}') 50 self.assert_raises(TemplateSyntaxError, env.from_string, '{% for foo, bar.baz in seq %}...{% endfor %}') 51 52 def test_markup_operations(self): 53 unsafe = '<script type="application/x-some-script">alert("foo");</script>' 54 safe = Markup('<em>username</em>') 55 x = Markup('foo') 56 57 class Foo(object): 58 59 def __html__(self): 60 return '<em>awesome</em>' 61 62 def __unicode__(self): 63 return 'awesome' 64 65 def test_template_data(self): 66 env = Environment(autoescape=True) 67 t = env.from_string('{% macro say_hello(name) %}<p>Hello {{ name }}!</p>{% endmacro %}{{ say_hello("<blink>foo</blink>") }}') 68 escaped_out = '<p>Hello <blink>foo</blink>!</p>' 69 70 def test_attr_filter(self): 71 env = SandboxedEnvironment() 72 tmpl = env.from_string('{{ cls|attr("__subclasses__")() }}') 73 self.assert_raises(SecurityError, tmpl.render, cls=int) 74 75 def test_binary_operator_intercepting(self): 76 77 def disable_op(left, right): 78 raise TemplateRuntimeError('that operator so does not work') 79 80 for expr, ctx, rv in (('1 + 2', {}, '3'), ('a + 2', {'a': 2}, '4')): 81 env = SandboxedEnvironment() 82 env.binop_table['+'] = disable_op 83 t = env.from_string('{{ %s }}' % expr) 84 env.intercepted_binops = frozenset(['+']) 85 t = env.from_string('{{ %s }}' % expr) 86 try: 87 t.render(ctx) 88 except TemplateRuntimeError as e: 89 pass 90 else: 91 self.fail('expected runtime error') 92 93 def test_unary_operator_intercepting(self): 94 95 def disable_op(arg): 96 raise TemplateRuntimeError('that operator so does not work') 97 98 for expr, ctx, rv in (('-1', {}, '-1'), ('-a', {'a': 2}, '-2')): 99 env = SandboxedEnvironment() 100 env.unop_table['-'] = disable_op 101 t = env.from_string('{{ %s }}' % expr) 102 env.intercepted_unops = frozenset(['-']) 103 t = env.from_string('{{ %s }}' % expr) 104 try: 105 t.render(ctx) 106 except TemplateRuntimeError as e: 107 pass 108 else: 109 self.fail('expected runtime error') 110 111 112 def suite(): 113 suite = unittest.TestSuite() 114 suite.addTest(unittest.makeSuite(SandboxTestCase)) 115 return suite