def test_unpickling(self): self.assertEqual(unpickle_context(pickle_context(Context())), flatten_context(Context())) context = Context({'test_var': 'TEST'}) pickled_context = pickle_context(context) unpickled_context = unpickle_context(pickled_context) self.assertEqual(flatten_context(context), unpickled_context)
def test_unpickling_with_template_and_pattern(self): context = Context({'test_var': 'TEST'}) template = '<!-- better be careful %s yikes -->' pattern = re.compile(r'.*<!-- better be careful (.*) yikes -->.*') pickled_context = pickle_context(context, template) unpickled_context = unpickle_context(pickled_context, pattern) self.assertEqual(flatten_context(context), unpickled_context)
def test_phased(self): context = Context({'test_var': 'TEST'}) first_render = compile_string(self.test_template, None).render(context) original_context = unpickle_context(first_render) self.assertNotEqual(flatten_context(context), original_context) pickled_context = '{# context "gAJ9cQFVCmNzcmZfdG9rZW5xAlULTk9UUFJPVklERURxA3Mu" endcontext #}' pickled_components = '{# components "gAJdcQFVH3BoYXNlZC50ZW1wbGF0ZXRhZ3MucGhhc2VkX3RhZ3NxAmEu" endcomponents #}' self.assertEqual(first_render, '%(delimiter)s{%% if 1 %%}test{%% endif %%}%(pickled_context)s%(pickled_components)s%(delimiter)sTEST' % dict(delimiter=settings.SECRET_DELIMITER, pickled_context=pickled_context, pickled_components=pickled_components))
def test_phased(self): context = Context({'test_var': 'TEST'}) first_render = compile_string(self.test_template, None).render(context) original_context = unpickle_context(first_render) self.assertNotEqual(flatten_context(context), original_context) pickled_context = pickle_context(Context({'csrf_token': 'NOTPROVIDED'})) self.assertEqual(first_render, '%(delimiter)s{%% if 1 %%}test{%% endif %%}%(pickled_context)s%(delimiter)sTEST' % dict(delimiter=settings.PHASED_SECRET_DELIMITER, pickled_context=pickled_context))
def test_second_pass(self): request = self.factory.get('/') context = Context({ 'test_var': 'TEST', 'test_var2': 'TEST2', 'test_condition': True, }) first_render = compile_string(self.test_template, None).render(context) original_context = unpickle_context(first_render) self.assertEqual(original_context.get('test_var'), 'TEST') second_render = second_pass_render(request, first_render) self.assertEqual(second_render, 'teststashedTEST')
def second_pass_render(request, content): """ Split on the secret delimiter and generate the token list by passing through text outside of phased blocks as single text tokens and tokenizing text inside the phased blocks. This ensures that nothing outside of the phased blocks is tokenized, thus eliminating the possibility of a template code injection vulnerability. """ result = tokens = [] for index, bit in enumerate(content.split(settings.PHASED_SECRET_DELIMITER)): if index % 2: tokens = Lexer(bit, None).tokenize() else: tokens.append(Token(TOKEN_TEXT, bit)) context = RequestContext(request, restore_csrf_token(request, unpickle_context(bit))) rendered = Parser(tokens).parse().render(context) if settings.PHASED_SECRET_DELIMITER in rendered: rendered = second_pass_render(request, rendered) result.append(rendered) return "".join(result)