@@ -71,8 +71,13 @@ body.index {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.wrapper-text-welcome, .logo {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-weight: 600;
|
||||
margin-left: ($baseline/2);
|
||||
}
|
||||
|
||||
.tagline {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<section class="content content-header">
|
||||
<header>
|
||||
## "edX Studio" should not be translated
|
||||
<h1>${_('Welcome to')}<span class="logo">edX Studio</span></h1>
|
||||
<h1><span class="wrapper-text-welcome">${_('Welcome to')}</span><span class="logo">edX Studio</span></h1>
|
||||
<p class="tagline">${_("Studio helps manage your courses online, so you can focus on teaching them")}</p>
|
||||
</header>
|
||||
</section>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<% 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/>
|
||||
|
||||
Reference in New Issue
Block a user