From 5773001f75cab9c6deefd79d5de60af044582125 Mon Sep 17 00:00:00 2001 From: Adeel Khan Date: Mon, 11 Dec 2017 16:25:47 +0500 Subject: [PATCH] Fix certificate's course title for xss tags injection. This fix would enable course author to selectively add basic html tags to course title, while removing any other injected tags that could execute javascript. LEARNER-3491 --- openedx/core/djangolib/markup.py | 23 +++++++++++++++++++++ openedx/core/djangolib/tests/test_markup.py | 18 +++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/openedx/core/djangolib/markup.py b/openedx/core/djangolib/markup.py index 77b081737c..0cea1d4af9 100644 --- a/openedx/core/djangolib/markup.py +++ b/openedx/core/djangolib/markup.py @@ -3,6 +3,8 @@ Utilities for use in Mako markup. """ import markupsafe +import bleach +from mako.filters import decode # Text() can be used to declare a string as plain text, as HTML() is used # for HTML. It simply wraps markupsafe's escape, which will HTML-escape if @@ -31,3 +33,24 @@ def HTML(html): # pylint: disable=invalid-name """ return markupsafe.Markup(html) + + +def strip_all_tags_but_br(string_to_strip): + """ + Strips all tags from a string except
+ + Usage: + <%page expression_filter="h"/> + <%! + from openedx.core.djangolib.markup import strip_all_tags_but_br + %> + ${accomplishment_course_title | n, strip_all_tags_but_br} + """ + + if string_to_strip is None: + string_to_strip = "" + + string_to_strip = decode.utf8(string_to_strip) + string_to_strip = bleach.clean(string_to_strip, tags=['br'], strip=True) + + return string_to_strip diff --git a/openedx/core/djangolib/tests/test_markup.py b/openedx/core/djangolib/tests/test_markup.py index cd6b9b01ec..f8a347bace 100644 --- a/openedx/core/djangolib/tests/test_markup.py +++ b/openedx/core/djangolib/tests/test_markup.py @@ -11,7 +11,7 @@ from django.utils.translation import ungettext from mako.template import Template from nose.plugins.attrib import attr -from openedx.core.djangolib.markup import HTML, Text +from openedx.core.djangolib.markup import HTML, Text, strip_all_tags_but_br @attr(shard=2) @@ -74,3 +74,19 @@ class FormatHtmlTest(unittest.TestCase): for i in [1, 2]: out = Text(ungettext("1 & {}", "2 & {}", i)).format(HTML("<>")) self.assertEqual(out, "{} & <>".format(i)) + + def test_strip_all_tags_but_br_filter(self): + """ Verify filter removes every tags except br """ + template = Template( + """ + <%page expression_filter="h"/> + <%! + from openedx.core.djangolib.markup import strip_all_tags_but_br + %> + ${" course
title