Spaces:
Paused
Paused
| #!/usr/bin/env python3 | |
| # run from dir above changedetectionio/ dir | |
| # python3 -m unittest changedetectionio.tests.unit.test_jinja2_security | |
| import unittest | |
| from changedetectionio import safe_jinja | |
| # mostly | |
| class TestJinja2SSTI(unittest.TestCase): | |
| def test_exception(self): | |
| import jinja2 | |
| # Where sandbox should kick in | |
| attempt_list = [ | |
| "My name is {{ self.__init__.__globals__.__builtins__.__import__('os').system('id') }}", | |
| "{{ self._TemplateReference__context.cycler.__init__.__globals__.os }}", | |
| "{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}", | |
| "{{cycler.__init__.__globals__.os.popen('id').read()}}", | |
| "{{joiner.__init__.__globals__.os.popen('id').read()}}", | |
| "{{namespace.__init__.__globals__.os.popen('id').read()}}", | |
| "{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/hello.txt', 'w').write('Hello here !') }}", | |
| "My name is {{ self.__init__.__globals__ }}", | |
| "{{ dict.__base__.__subclasses__() }}" | |
| ] | |
| for attempt in attempt_list: | |
| with self.assertRaises(jinja2.exceptions.SecurityError): | |
| safe_jinja.render(attempt) | |
| def test_exception_debug_calls(self): | |
| import jinja2 | |
| # Where sandbox should kick in - configs and debug calls | |
| attempt_list = [ | |
| "{% debug %}", | |
| ] | |
| for attempt in attempt_list: | |
| # Usually should be something like 'Encountered unknown tag 'debug'.' | |
| with self.assertRaises(jinja2.exceptions.TemplateSyntaxError): | |
| safe_jinja.render(attempt) | |
| # https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection/jinja2-ssti#accessing-global-objects | |
| def test_exception_empty_calls(self): | |
| import jinja2 | |
| attempt_list = [ | |
| "{{config}}", | |
| "{{ debug }}" | |
| "{{[].__class__}}", | |
| ] | |
| for attempt in attempt_list: | |
| self.assertEqual(len(safe_jinja.render(attempt)), 0, f"string test '{attempt}' is correctly empty") | |
| if __name__ == '__main__': | |
| unittest.main() | |