fix: sanitize HTML for course overview & sidebar

The "overview" and "about_sidebar_html" fields in the
CoursewareInformation view (/api/courseware/course/{courseId}) were
returning unsanitized HTML and relying on the client to sanitize it.
This commit shifts that work to the server side (clean_dangerous_html)
to remove potentially dangerous tags when generating the response. The
source of this data is modified in the "Settings and Details" section
of a course in Studio.
This commit is contained in:
David Ormsbee
2025-12-12 10:02:41 -05:00
parent 2637cc6b0f
commit 53c25b9cd8
2 changed files with 14 additions and 4 deletions

View File

@@ -662,15 +662,20 @@ class CoursewareMetaTestViews(BaseCoursewareTests):
)
def test_about_sidebar_html_property(self, waffle_enabled, mock_get_course_about_section):
"""
Test about_sidebar_html property with different waffle settings
Test about_sidebar_html property with different waffle settings.
Ensure that when a value is returned, <script> tags are stripped.
"""
mock_get_course_about_section.return_value = '<div>About Course</div>'
# We're mocking the underlying method used to grab both the overview
# html and the about_sidebar_html, so we can test sanitization on both.
mock_get_course_about_section.return_value = '<div>About Course<script>alert("warning!");</script></div>'
with override_waffle_switch(ENABLE_COURSE_ABOUT_SIDEBAR_HTML, active=waffle_enabled):
meta = self.create_courseware_meta()
if waffle_enabled:
assert meta.about_sidebar_html == '<div>About Course</div>'
else:
assert meta.about_sidebar_html is None
assert meta.overview == '<div>About Course</div>'
@ddt.ddt

View File

@@ -63,6 +63,7 @@ from openedx.core.djangoapps.agreements.api import get_integrity_signature
from openedx.core.djangoapps.courseware_api.utils import get_celebrations_dict
from openedx.core.djangoapps.enrollments.permissions import ENROLL_IN_COURSE
from openedx.core.djangoapps.programs.utils import ProgramProgressMeter
from openedx.core.djangolib.markup import clean_dangerous_html
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
from openedx.core.lib.courses import get_course_by_id
@@ -516,7 +517,9 @@ class CoursewareMeta:
Returns the HTML content for the course about section.
"""
if ENABLE_COURSE_ABOUT_SIDEBAR_HTML.is_enabled():
return get_course_about_section(self.request, self.course, "about_sidebar_html")
return clean_dangerous_html(
get_course_about_section(self.request, self.course, "about_sidebar_html")
)
return None
@property
@@ -524,7 +527,9 @@ class CoursewareMeta:
"""
Returns the overview HTML content for the course.
"""
return get_course_about_section(self.request, self.course, "overview")
return clean_dangerous_html(
get_course_about_section(self.request, self.course, "overview")
)
@method_decorator(transaction.non_atomic_requests, name='dispatch')