Commit 2926c943 by Diana Huang

Prevent XSS attack via submission_history page.

Conflicts:
	lms/djangoapps/courseware/tests/test_views.py
parent ab482277
......@@ -6,8 +6,10 @@ from django.http import Http404
from django.test.utils import override_settings
from django.contrib.auth.models import User
from django.test.client import RequestFactory
from django.core.urlresolvers import reverse
from student.models import CourseEnrollment
from student.tests.factories import AdminFactory
from xmodule.modulestore.django import modulestore
import courseware.views as views
......@@ -124,3 +126,27 @@ class ViewsTestCase(TestCase):
self.assertContains(result, expected_end_text)
else:
self.assertNotContains(result, "Classes End")
def test_submission_history_xss(self):
# log into a staff account
admin = AdminFactory()
self.client.login(username=admin.username, password='test')
# try it with an existing user and a malicious location
url = reverse('submission_history', kwargs={
'course_id': self.course_id,
'student_username': 'dummy',
'location': '<script>alert("hello");</script>'
})
response = self.client.get(url)
self.assertFalse('<script>' in response.content)
# try it with a malicious user and a non-existent location
url = reverse('submission_history', kwargs={
'course_id': self.course_id,
'student_username': '<script>alert("hello");</script>',
'location': 'dummy'
})
response = self.client.get(url)
self.assertFalse('<script>' in response.content)
......@@ -14,6 +14,7 @@ from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string
from django_future.csrf import ensure_csrf_cookie
from django.views.decorators.cache import cache_control
from markupsafe import escape
from courseware import grades
from courseware.access import has_access
......@@ -709,19 +710,16 @@ def submission_history(request, course_id, student_username, location):
module_state_key=location,
student_id=student.id)
except User.DoesNotExist:
return HttpResponse("User {0} does not exist.".format(student_username))
return HttpResponse(escape("User {0} does not exist.".format(student_username)))
except StudentModule.DoesNotExist:
return HttpResponse("{0} has never accessed problem {1}"
.format(student_username, location))
return HttpResponse(escape("{0} has never accessed problem {1}".format(student_username, location)))
history_entries = StudentModuleHistory.objects \
.filter(student_module=student_module).order_by('-id')
history_entries = StudentModuleHistory.objects.filter(student_module=student_module).order_by('-id')
# If no history records exist, let's force a save to get history started.
if not history_entries:
student_module.save()
history_entries = StudentModuleHistory.objects \
.filter(student_module=student_module).order_by('-id')
history_entries = StudentModuleHistory.objects.filter(student_module=student_module).order_by('-id')
context = {
'history_entries': history_entries,
......
<% import json %>
<h3>${username} > ${course_id} > ${location}</h3>
<h3>${username | h} > ${course_id | h} > ${location | h}</h3>
% for i, entry in enumerate(history_entries):
<hr/>
......
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