Commit a64d9268 by Ned Batchelder

Merge pull request #7399 from edx/ned/plat-462

Make sure slashes in JSON content don't end script tags. PLAT-462
parents e03813da 6928035c
......@@ -113,11 +113,10 @@ def wrap_xblock(runtime_class, block, view, frag, context, usage_id_serializer,
}
if hasattr(frag, 'json_init_args') and frag.json_init_args is not None:
template_context['js_init_parameters'] = json.dumps(frag.json_init_args)
template_context['js_pass_parameters'] = True
# Replace / with \/ so that "</script>" in the data won't break things.
template_context['js_init_parameters'] = json.dumps(frag.json_init_args).replace("/", r"\/")
else:
template_context['js_init_parameters'] = ""
template_context['js_pass_parameters'] = False
return wrap_fragment(frag, render_to_string('xblock_wrapper.html', template_context))
......
<div class="${' '.join(classes) | n}" ${data_attributes}>
% if js_pass_parameters:
% if js_init_parameters:
<script type="json/xblock-args" class="xblock_json_init_args">
${js_init_parameters}
</script>
......
......@@ -16,10 +16,12 @@ from django.contrib.auth.models import AnonymousUser
from mock import MagicMock, patch, Mock
from opaque_keys.edx.keys import UsageKey, CourseKey
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from courseware.module_render import hash_resource
from xblock.field_data import FieldData
from xblock.runtime import Runtime
from xblock.fields import ScopeIds
from xblock.core import XBlock
from xblock.fragment import Fragment
from capa.tests.response_xml_factory import OptionResponseXMLFactory
from courseware import module_render as render
......@@ -660,6 +662,53 @@ class TestHtmlModifiers(ModuleStoreTestCase):
)
class XBlockWithJsonInitData(XBlock):
"""
Pure XBlock to use in tests, with JSON init data.
"""
the_json_data = None
def student_view(self, context=None): # pylint: disable=unused-argument
"""
A simple view that returns just enough to test.
"""
frag = Fragment(u"Hello there!")
frag.add_javascript(u'alert("Hi!");')
frag.initialize_js('ThumbsBlock', self.the_json_data)
return frag
@ddt.ddt
class JsonInitDataTest(ModuleStoreTestCase):
"""Tests for JSON data injected into the JS init function."""
@ddt.data(
({'a': 17}, '''{"a": 17}'''),
({'xss': '</script>alert("XSS")'}, r'''{"xss": "<\/script>alert(\"XSS\")"}'''),
)
@ddt.unpack
@XBlock.register_temp_plugin(XBlockWithJsonInitData, identifier='withjson')
def test_json_init_data(self, json_data, json_output):
XBlockWithJsonInitData.the_json_data = json_data
mock_user = UserFactory()
mock_request = MagicMock()
mock_request.user = mock_user
course = CourseFactory()
descriptor = ItemFactory(category='withjson', parent=course)
field_data_cache = FieldDataCache([course, descriptor], course.id, mock_user) # pylint: disable=no-member
module = render.get_module_for_descriptor(
mock_user,
mock_request,
descriptor,
field_data_cache,
course.id, # pylint: disable=no-member
)
html = module.render(STUDENT_VIEW).content
self.assertIn(json_output, html)
# No matter what data goes in, there should only be one close-script tag.
self.assertEqual(html.count("</script>"), 1)
class ViewInStudioTest(ModuleStoreTestCase):
"""Tests for the 'View in Studio' link visiblity."""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment