Commit b79b6e6a by Qubad786

Making templates more safe from XSS

parent 95ffe7cd
<%page expression_filter="h"/>
<%inherit file="base.html" /> <%inherit file="base.html" />
<%def name="online_help_token()"> <%def name="online_help_token()">
<% <%
...@@ -10,6 +11,7 @@ else: ...@@ -10,6 +11,7 @@ else:
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%! <%!
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import Text, HTML
from openedx.core.djangolib.js_utils import ( from openedx.core.djangolib.js_utils import (
dump_js_escaped_json, js_escaped_string dump_js_escaped_json, js_escaped_string
) )
...@@ -44,11 +46,11 @@ else: ...@@ -44,11 +46,11 @@ else:
<div class="introduction"> <div class="introduction">
## Translators: ".tar.gz" is a file extension, and files with that extension are called "gzipped tar files": these terms should not be translated ## Translators: ".tar.gz" is a file extension, and files with that extension are called "gzipped tar files": these terms should not be translated
%if library: %if library:
<p>${_("Be sure you want to import a library before continuing. The contents of the imported library will replace the contents of the existing library. {em_start}You cannot undo a library import{em_end}. Before you proceed, we recommend that you export the current library, so that you have a backup copy of it.").format(em_start='<strong>', em_end="</strong>")}</p> <p>${Text(_("Be sure you want to import a library before continuing. The contents of the imported library will replace the contents of the existing library. {em_start}You cannot undo a library import{em_end}. Before you proceed, we recommend that you export the current library, so that you have a backup copy of it.")).format(em_start=HTML('<strong>'), em_end=HTML('</strong>'))}</p>
<p>${_("The library that you import must be in a .tar.gz file (that is, a .tar file compressed with GNU Zip). This .tar.gz file must contain a library.xml file. It may also contain other files.")}</p> <p>${_("The library that you import must be in a .tar.gz file (that is, a .tar file compressed with GNU Zip). This .tar.gz file must contain a library.xml file. It may also contain other files.")}</p>
<p>${_("The import process has five stages. During the first two stages, you must stay on this page. You can leave this page after the Unpacking stage has completed. We recommend, however, that you don't make important changes to your library until the import operation has completed.")}</p> <p>${_("The import process has five stages. During the first two stages, you must stay on this page. You can leave this page after the Unpacking stage has completed. We recommend, however, that you don't make important changes to your library until the import operation has completed.")}</p>
%else: %else:
<p>${_("Be sure you want to import a course before continuing. The contents of the imported course will replace the contents of the existing course. {em_start}You cannot undo a course import{em_end}. Before you proceed, we recommend that you export the current course, so that you have a backup copy of it.").format(em_start='<strong>', em_end="</strong>")}</p> <p>${Text(_("Be sure you want to import a course before continuing. The contents of the imported course will replace the contents of the existing course. {em_start}You cannot undo a course import{em_end}. Before you proceed, we recommend that you export the current course, so that you have a backup copy of it.")).format(em_start=HTML('<strong>'), em_end=HTML('</strong>'))}</p>
<p>${_("The course that you import must be in a .tar.gz file (that is, a .tar file compressed with GNU Zip). This .tar.gz file must contain a course.xml file. It may also contain other files.")}</p> <p>${_("The course that you import must be in a .tar.gz file (that is, a .tar file compressed with GNU Zip). This .tar.gz file must contain a course.xml file. It may also contain other files.")}</p>
<p>${_("The import process has five stages. During the first two stages, you must stay on this page. You can leave this page after the Unpacking stage has completed. We recommend, however, that you don't make important changes to your course until the import operation has completed.")}</p> <p>${_("The import process has five stages. During the first two stages, you must stay on this page. You can leave this page after the Unpacking stage has completed. We recommend, however, that you don't make important changes to your course until the import operation has completed.")}</p>
%endif %endif
......
<%page expression_filter="h"/>
<%inherit file="base.html" /> <%inherit file="base.html" />
<%def name="online_help_token()"><% return "register" %></%def> <%def name="online_help_token()"><% return "register" %></%def>
<%! <%!
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import Text, HTML
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
%> %>
...@@ -67,14 +69,17 @@ from django.core.urlresolvers import reverse ...@@ -67,14 +69,17 @@ from django.core.urlresolvers import reverse
<li class="field checkbox required" id="field-tos"> <li class="field checkbox required" id="field-tos">
<input id="tos" name="terms_of_service" type="checkbox" value="true" /> <input id="tos" name="terms_of_service" type="checkbox" value="true" />
<label for="tos"> <label for="tos">
${_("I agree to the {a_start} Terms of Service {a_end}").format(a_start='<a data-rel="edx.org" href="{}">'.format(marketing_link('TOS')), a_end="</a>")} ${Text(_("I agree to the {a_start} Terms of Service {a_end}")).format(
a_start=HTML('<a data-rel="edx.org" href="{}">').format(marketing_link('TOS')),
a_end=HTML("</a>")
)}
</label> </label>
</li> </li>
</ol> </ol>
</fieldset> </fieldset>
<div class="form-actions"> <div class="form-actions">
<button type="submit" id="submit" name="submit" class="action action-primary">${_("Create My Account &amp; Start Authoring Courses")}</button> <button type="submit" id="submit" name="submit" class="action action-primary">${_("Create My Account & Start Authoring Courses")}</button>
</div> </div>
<!-- no honor code for CMS, but need it because we're using the lms student object --> <!-- no honor code for CMS, but need it because we're using the lms student object -->
......
<%page expression_filter="h"/>
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%! <%!
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from courseware.courses import get_course_about_section
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from edxmako.shortcuts import marketing_link from edxmako.shortcuts import marketing_link
from openedx.core.djangolib.markup import HTML, Text
from openedx.core.djangolib.js_utils import js_escaped_string
from openedx.core.lib.courses import course_image_url from openedx.core.lib.courses import course_image_url
from courseware.courses import get_course_about_section
%> %>
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<%block name="headextra"> <%block name="headextra">
## OG (Open Graph) title and description added below to give social media info to display ## OG (Open Graph) title and description added below to give social media info to display
## (https://developers.facebook.com/docs/opengraph/howtos/maximizing-distribution-media-content#tags) ## (https://developers.facebook.com/docs/opengraph/howtos/maximizing-distribution-media-content#tags)
<meta property="og:title" content="${course.display_name_with_default_escaped}" /> <meta property="og:title" content="${course.display_name_with_default}" />
<meta property="og:description" content="${get_course_about_section(request, course, 'short_description')}" /> <meta property="og:description" content="${get_course_about_section(request, course, 'short_description')}" />
</%block> </%block>
...@@ -31,21 +36,21 @@ from openedx.core.lib.courses import course_image_url ...@@ -31,21 +36,21 @@ from openedx.core.lib.courses import course_image_url
% if can_add_course_to_cart: % if can_add_course_to_cart:
add_course_complete_handler = function(jqXHR, textStatus) { add_course_complete_handler = function(jqXHR, textStatus) {
if (jqXHR.status == 200) { if (jqXHR.status == 200) {
location.href = "${cart_link}"; location.href = "${cart_link| n, js_escaped_string}";
} }
if (jqXHR.status == 400) { if (jqXHR.status == 400) {
$("#register_error") $("#register_error")
.html(jqXHR.responseText ? jqXHR.responseText : "${_("An error occurred. Please try again later.")}") .text(jqXHR.responseText ? jqXHR.responseText : "${_('An error occurred. Please try again later.')| n, js_escaped_string}")
.css("display", "block"); .css("display", "block");
} }
else if (jqXHR.status == 403) { else if (jqXHR.status == 403) {
location.href = "${reg_then_add_to_cart_link}"; location.href = "${reg_then_add_to_cart_link| n, js_escaped_string}";
} }
}; };
$("#add_to_cart_post").click(function(event){ $("#add_to_cart_post").click(function(event){
$.ajax({ $.ajax({
url: "${reverse('add_course_to_cart', args=[course.id.to_deprecated_string()])}", url: "${reverse('add_course_to_cart', args=[course.id.to_deprecated_string()])| n, js_escaped_string}",
type: "POST", type: "POST",
/* Rant: HAD TO USE COMPLETE B/C PROMISE.DONE FOR SOME REASON DOES NOT WORK ON THIS PAGE. */ /* Rant: HAD TO USE COMPLETE B/C PROMISE.DONE FOR SOME REASON DOES NOT WORK ON THIS PAGE. */
complete: add_course_complete_handler complete: add_course_complete_handler
...@@ -53,27 +58,32 @@ from openedx.core.lib.courses import course_image_url ...@@ -53,27 +58,32 @@ from openedx.core.lib.courses import course_image_url
event.preventDefault(); event.preventDefault();
}); });
% endif % endif
## making the conditional around this entire JS block for sanity ## making the conditional around this entire JS block for sanity
%if settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain: %if settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
<% <%
perms_error = _('The currently logged-in user account does not have permission to enroll in this course. ' perms_error = Text(
_('The currently logged-in user account does not have permission to enroll in this course. '
'You may need to {start_logout_tag}log out{end_tag} then try the enroll button again. ' 'You may need to {start_logout_tag}log out{end_tag} then try the enroll button again. '
'Please visit the {start_help_tag}help page{end_tag} for a possible solution.').format( 'Please visit the {start_help_tag}help page{end_tag} for a possible solution.')
start_help_tag="<a href='{url}'>".format(url=marketing_link('FAQ')), end_tag='</a>', ).format(
start_logout_tag="<a href='{url}'>".format(url=reverse('logout')) start_help_tag=HTML("<a href='{url}'>").format(url=marketing_link('FAQ')),
end_tag=HTML('</a>'),
start_logout_tag=HTML("<a href='{url}'>").format(url=reverse('logout'))
) )
%> %>
$('#class_enroll_form').on('ajax:complete', function(event, xhr) { $('#class_enroll_form').on('ajax:complete', function(event, xhr) {
if(xhr.status == 200) { if(xhr.status == 200) {
location.href = "${reverse('dashboard')}"; location.href = "${reverse('dashboard')| n, js_escaped_string}";
} else if (xhr.status == 403) { } else if (xhr.status == 403) {
location.href = "${reverse('course-specific-register', args=[course.id.to_deprecated_string()])}?course_id=${course.id | u}&enrollment_action=enroll"; location.href = "${reverse('course-specific-register', args=[course.id.to_deprecated_string()])| n, js_escaped_string}?course_id=${course.id| n, js_escaped_string}&enrollment_action=enroll";
} else if (xhr.status == 400) { //This means the user did not have permission } else if (xhr.status == 400) {//This means the user did not have permission
$('#register_error').html("${perms_error}").css("display", "block"); edx.HtmlUtils.setHtml(
$('#register_error'),
"${perms_error}"
)
} else { } else {
$('#register_error').html( $('#register_error').text(
(xhr.responseText ? xhr.responseText : "${_("An error occurred. Please try again later.")}") (xhr.responseText ? xhr.responseText : "${_('An error occurred. Please try again later.')| n, js_escaped_string}")
).css("display", "block"); ).css("display", "block");
} }
}); });
...@@ -83,16 +93,16 @@ from openedx.core.lib.courses import course_image_url ...@@ -83,16 +93,16 @@ from openedx.core.lib.courses import course_image_url
$('#class_enroll_form').on('ajax:complete', function(event, xhr) { $('#class_enroll_form').on('ajax:complete', function(event, xhr) {
if(xhr.status == 200) { if(xhr.status == 200) {
if (xhr.responseText == "") { if (xhr.responseText == "") {
location.href = "${reverse('dashboard')}"; location.href = "${reverse('dashboard')| n, js_escaped_string}";
} }
else { else {
location.href = xhr.responseText; location.href = xhr.responseText;
} }
} else if (xhr.status == 403) { } else if (xhr.status == 403) {
location.href = "${reverse('register_user')}?course_id=${course.id | u}&enrollment_action=enroll"; location.href = "${reverse('register_user')| n, js_escaped_string}?course_id=${course.id| n, js_escaped_string}&enrollment_action=enroll";
} else { } else {
$('#register_error').html( $('#register_error').text(
(xhr.responseText ? xhr.responseText : "${_("An error occurred. Please try again later.")}") (xhr.responseText ? xhr.responseText : "${_('An error occurred. Please try again later.')| n, js_escaped_string}")
).css("display", "block"); ).css("display", "block");
} }
}); });
...@@ -105,7 +115,7 @@ from openedx.core.lib.courses import course_image_url ...@@ -105,7 +115,7 @@ from openedx.core.lib.courses import course_image_url
<script src="${static.url('js/course_info.js')}"></script> <script src="${static.url('js/course_info.js')}"></script>
</%block> </%block>
<%block name="pagetitle">${course.display_name_with_default_escaped}</%block> <%block name="pagetitle">${course.display_name_with_default}</%block>
<section class="course-info"> <section class="course-info">
<header class="course-profile"> <header class="course-profile">
...@@ -114,8 +124,8 @@ from openedx.core.lib.courses import course_image_url ...@@ -114,8 +124,8 @@ from openedx.core.lib.courses import course_image_url
<section class="intro"> <section class="intro">
<div class="heading-group"> <div class="heading-group">
<h1> <h1>
${course.display_name_with_default_escaped} ${course.display_name_with_default}
<a href="#">${course.display_org_with_default | h}</a> <a href="#">${course.display_org_with_default}</a>
</h1> </h1>
</div> </div>
...@@ -134,7 +144,10 @@ from openedx.core.lib.courses import course_image_url ...@@ -134,7 +144,10 @@ from openedx.core.lib.courses import course_image_url
%elif in_cart: %elif in_cart:
<span class="add-to-cart"> <span class="add-to-cart">
${_('This course is in your <a href="{cart_link}">cart</a>.').format(cart_link=cart_link)} ${Text(_('This course is in your {link_start}cart{link_end}.')).format(
link_start=HTML('<a href="{cart_link}">').format(cart_link=cart_link),
link_end=HTML('</a>')
)}
</span> </span>
% elif is_course_full: % elif is_course_full:
<span class="register disabled"> <span class="register disabled">
...@@ -161,8 +174,12 @@ from openedx.core.lib.courses import course_image_url ...@@ -161,8 +174,12 @@ from openedx.core.lib.courses import course_image_url
reg_element_id = "" reg_element_id = ""
%> %>
<a href="${reg_href}" class="add-to-cart" id="${reg_element_id}"> <a href="${reg_href}" class="add-to-cart" id="${reg_element_id}">
${_("Add {course_name} to Cart <span>({price} USD)</span>")\ ${Text(_("Add {course_name} to Cart {span_start}({price} USD){span_end}")).format(
.format(course_name=course.display_number_with_default, price=course_price)} course_name=course.display_number_with_default,
price=course_price,
span_start = HTML('<span>'),
span_end = HTML('</span>')
)}
</a> </a>
<div id="register_error"></div> <div id="register_error"></div>
%else: %else:
...@@ -177,7 +194,7 @@ from openedx.core.lib.courses import course_image_url ...@@ -177,7 +194,7 @@ from openedx.core.lib.courses import course_image_url
href_class = "register" href_class = "register"
%> %>
<a href="${reg_href}" class="${href_class}"> <a href="${reg_href}" class="${href_class}">
${_("Enroll in {course_name}").format(course_name=course.display_number_with_default) | h} ${_("Enroll in {course_name}").format(course_name=course.display_number_with_default)}
</a> </a>
<div id="register_error"></div> <div id="register_error"></div>
%endif %endif
...@@ -211,7 +228,7 @@ from openedx.core.lib.courses import course_image_url ...@@ -211,7 +228,7 @@ from openedx.core.lib.courses import course_image_url
% endif % endif
<div class="inner-wrapper"> <div class="inner-wrapper">
${get_course_about_section(request, course, "overview")} ${HTML(get_course_about_section(request, course, "overview"))}
</div> </div>
</section> </section>
...@@ -221,7 +238,7 @@ from openedx.core.lib.courses import course_image_url ...@@ -221,7 +238,7 @@ from openedx.core.lib.courses import course_image_url
<%include file="course_about_sidebar_header.html" /> <%include file="course_about_sidebar_header.html" />
<ol class="important-dates"> <ol class="important-dates">
<li class="important-dates-item"><i class="icon fa fa-info-circle"></i><p class="important-dates-item-title">${_("Course Number")}</p><span class="important-dates-item-text course-number">${course.display_number_with_default | h}</span></li> <li class="important-dates-item"><i class="icon fa fa-info-circle"></i><p class="important-dates-item-title">${_("Course Number")}</p><span class="important-dates-item-text course-number">${course.display_number_with_default}</span></li>
% if not course.start_date_is_still_default: % if not course.start_date_is_still_default:
<li class="important-dates-item"><i class="icon fa fa-calendar"></i><p class="important-dates-item-title">${_("Classes Start")}</p><span class="important-dates-item-text start-date">${course.start_datetime_text()}</span></li> <li class="important-dates-item"><i class="icon fa fa-calendar"></i><p class="important-dates-item-title">${_("Classes Start")}</p><span class="important-dates-item-text start-date">${course.start_datetime_text()}</span></li>
% endif % endif
...@@ -263,9 +280,9 @@ from openedx.core.lib.courses import course_image_url ...@@ -263,9 +280,9 @@ from openedx.core.lib.courses import course_image_url
## Multiple pre-requisite courses are not supported on frontend that's why we are pulling first element ## Multiple pre-requisite courses are not supported on frontend that's why we are pulling first element
<span class="important-dates-item-text pre-requisite"><a href="${prc_target}">${pre_requisite_courses[0]['display']}</a></span> <span class="important-dates-item-text pre-requisite"><a href="${prc_target}">${pre_requisite_courses[0]['display']}</a></span>
<p class="tip"> <p class="tip">
${_("You must successfully complete {link_start}{prc_display}{link_end} before you begin this course.").format( ${Text(_("You must successfully complete {link_start}{prc_display}{link_end} before you begin this course.")).format(
link_start='<a href="{}">'.format(prc_target), link_start=HTML('<a href="{}">').format(prc_target),
link_end='</a>', link_end=HTML('</a>'),
prc_display=pre_requisite_courses[0]['display'], prc_display=pre_requisite_courses[0]['display'],
)} )}
</p> </p>
...@@ -312,7 +329,7 @@ from openedx.core.lib.courses import course_image_url ...@@ -312,7 +329,7 @@ from openedx.core.lib.courses import course_image_url
<form id="class_enroll_form" method="post" data-remote="true" action="${reverse('change_enrollment')}"> <form id="class_enroll_form" method="post" data-remote="true" action="${reverse('change_enrollment')}">
<fieldset class="enroll_fieldset"> <fieldset class="enroll_fieldset">
<legend class="sr">${_("Enroll")}</legend> <legend class="sr">${_("Enroll")}</legend>
<input name="course_id" type="hidden" value="${course.id | h}"> <input name="course_id" type="hidden" value="${course.id}">
<input name="enrollment_action" type="hidden" value="enroll"> <input name="enrollment_action" type="hidden" value="enroll">
</fieldset> </fieldset>
<div class="submit"> <div class="submit">
......
<%page expression_filter="h"/>
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%! <%!
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
...@@ -20,7 +21,7 @@ from django.conf import settings ...@@ -20,7 +21,7 @@ from django.conf import settings
## Twitter account. {url} should appear at the end of the text. ## Twitter account. {url} should appear at the end of the text.
tweet_text = _("I just enrolled in {number} {title} through {account}: {url}").format( tweet_text = _("I just enrolled in {number} {title} through {account}: {url}").format(
number=course.number, number=course.number,
title=course.display_name_with_default_escaped, title=course.display_name_with_default,
account=static.get_value('course_about_twitter_account', settings.PLATFORM_TWITTER_ACCOUNT), account=static.get_value('course_about_twitter_account', settings.PLATFORM_TWITTER_ACCOUNT),
url=u"http://{domain}{path}".format( url=u"http://{domain}{path}".format(
domain=site_domain, domain=site_domain,
...@@ -35,7 +36,7 @@ from django.conf import settings ...@@ -35,7 +36,7 @@ from django.conf import settings
subject=_("Take a course with {platform} online").format(platform=platform_name), subject=_("Take a course with {platform} online").format(platform=platform_name),
body=_("I just enrolled in {number} {title} through {platform} {url}").format( body=_("I just enrolled in {number} {title} through {platform} {url}").format(
number=course.number, number=course.number,
title=course.display_name_with_default_escaped, title=course.display_name_with_default,
platform=platform_name, platform=platform_name,
url=u"http://{domain}{path}".format( url=u"http://{domain}{path}".format(
domain=site_domain, domain=site_domain,
......
<%! from django.utils.translation import ugettext as _ %> <%page expression_filter="h"/>
<%!
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import HTML
%>
<section> <section>
<div class="recent-updates"> <div class="recent-updates">
% for index, update in enumerate(visible_updates): % for index, update in enumerate(visible_updates):
...@@ -15,7 +19,7 @@ ...@@ -15,7 +19,7 @@
></button> ></button>
% endif % endif
<div class="toggle-visibility-element article-content ${'hidden' if index >= 1 else ''}" id="msg-content-${index}"> <div class="toggle-visibility-element article-content ${'hidden' if index >= 1 else ''}" id="msg-content-${index}">
${update.get("content")} ${HTML(update.get("content"))}
</div> </div>
</article> </article>
% endfor % endfor
...@@ -43,7 +47,7 @@ ...@@ -43,7 +47,7 @@
aria-controls="msg-content-${index + len(visible_updates)}" aria-controls="msg-content-${index + len(visible_updates)}"
aria-expanded="false" aria-expanded="false"
></button> ></button>
<div class="toggle-visibility-element article-content hidden" id="msg-content-${index + len(visible_updates)}">${update.get("content")}</div> <div class="toggle-visibility-element article-content hidden" id="msg-content-${index + len(visible_updates)}">${HTML(update.get("content"))}</div>
</article> </article>
% endfor % endfor
</div> </div>
......
<%page expression_filter="h"/>
<div class="date-summary-container"> <div class="date-summary-container">
<div class="date-summary date-summary-${css_class}"> <div class="date-summary date-summary-${css_class}">
% if title: % if title:
......
<div id="problem_${element_id}" class="problems-wrapper" data-problem-id="${id}" data-url="${ajax_url}" data-progress_status="${progress_status}" data-progress_detail="${progress_detail}" data-content="${content | h}"></div> <%page expression_filter="h"/>
<div id="problem_${element_id}" class="problems-wrapper" data-problem-id="${id}" data-url="${ajax_url}" data-progress_status="${progress_status}" data-progress_detail="${progress_detail}" data-content="${content}"></div>
\ No newline at end of file
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