Commit a864b450 by Robert Raposa Committed by GitHub

Merge pull request #15436 from edx/robrap/rename-xss-linter

Rename xss linter.
parents 9329a5e3 b370fe23
...@@ -343,7 +343,7 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/pages/base_page ...@@ -343,7 +343,7 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/pages/base_page
updateHtml: function(element, html) { updateHtml: function(element, html) {
// Replace the element with the new HTML content, rather than adding // Replace the element with the new HTML content, rather than adding
// it as child elements. // it as child elements.
this.$el = $(html).replaceAll(element); // safe-lint: disable=javascript-jquery-insertion this.$el = $(html).replaceAll(element); // xss-lint: disable=javascript-jquery-insertion
} }
}); });
temporaryView = new TemporaryXBlockView({ temporaryView = new TemporaryXBlockView({
......
...@@ -344,7 +344,7 @@ ...@@ -344,7 +344,7 @@
for (i = 0; i < options.length; i += 1) { for (i = 0; i < options.length; i += 1) {
inner = /\s*\|\|(.*?)\|\|/.exec(options[i]); inner = /\s*\|\|(.*?)\|\|/.exec(options[i]);
if (inner) { if (inner) {
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
demandhints += ' <hint>' + inner[1].trim() + '</hint>\n'; demandhints += ' <hint>' + inner[1].trim() + '</hint>\n';
} }
} }
...@@ -601,9 +601,9 @@ ...@@ -601,9 +601,9 @@
hintLine = ''; hintLine = '';
if (textHint.hint) { if (textHint.hint) {
firstAnswer = textHint.nothint; firstAnswer = textHint.nothint;
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
hintLine = ' <correcthint' + textHint.labelassign + '>' + hintLine = ' <correcthint' + textHint.labelassign + '>' +
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
textHint.hint + '</correcthint>\n'; textHint.hint + '</correcthint>\n';
} }
...@@ -611,16 +611,16 @@ ...@@ -611,16 +611,16 @@
if (isRangeToleranceCase(firstAnswer)) { if (isRangeToleranceCase(firstAnswer)) {
// [5, 7) or (5, 7), or (1.2345 * (2+3), 7*4 ] - range tolerance case // [5, 7) or (5, 7), or (1.2345 * (2+3), 7*4 ] - range tolerance case
// = (5*2)*3 should not be used as range tolerance // = (5*2)*3 should not be used as range tolerance
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
numericalResponseString = '<numericalresponse answer="' + firstAnswer + '">\n'; numericalResponseString = '<numericalresponse answer="' + firstAnswer + '">\n';
} else { } else {
answerData = getAnswerData(firstAnswer); answerData = getAnswerData(firstAnswer);
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
numericalResponseString = '<numericalresponse answer="' + answerData.answer + '">\n'; numericalResponseString = '<numericalresponse answer="' + answerData.answer + '">\n';
if (answerData.default) { if (answerData.default) {
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
numericalResponseString += ' <responseparam type="tolerance" default="' + numericalResponseString += ' <responseparam type="tolerance" default="' +
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
answerData.default + '" />\n'; answerData.default + '" />\n';
} }
} }
...@@ -644,15 +644,15 @@ ...@@ -644,15 +644,15 @@
} }
if (additionalTextHint.hint) { if (additionalTextHint.hint) {
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
additionalHintLine = '<correcthint' + additionalHintLine = '<correcthint' +
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
additionalTextHint.labelassign + '>' + additionalTextHint.labelassign + '>' +
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
additionalTextHint.hint + '</correcthint>'; additionalTextHint.hint + '</correcthint>';
} }
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
additionalAnswerString += ' <additional_answer answer="' + orMatch[1] + '">'; additionalAnswerString += ' <additional_answer answer="' + orMatch[1] + '">';
additionalAnswerString += additionalHintLine; additionalAnswerString += additionalHintLine;
additionalAnswerString += '</additional_answer>\n'; additionalAnswerString += '</additional_answer>\n';
...@@ -765,7 +765,7 @@ ...@@ -765,7 +765,7 @@
responseTypesSelector = responseTypes.join(', '); responseTypesSelector = responseTypes.join(', ');
// make temporary xml // make temporary xml
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
$xml = $($.parseXML('<prob>' + xml + '</prob>')); $xml = $($.parseXML('<prob>' + xml + '</prob>'));
responseType = $xml.find(responseTypesSelector); responseType = $xml.find(responseTypesSelector);
...@@ -783,7 +783,7 @@ ...@@ -783,7 +783,7 @@
} }
if (beforeInputtype) { if (beforeInputtype) {
// safe-lint: disable=javascript-jquery-insert-into-target // xss-lint: disable=javascript-jquery-insert-into-target
responseType[0].insertBefore(child, inputtype); responseType[0].insertBefore(child, inputtype);
} else { } else {
responseType[0].appendChild(child); responseType[0].appendChild(child);
...@@ -814,11 +814,11 @@ ...@@ -814,11 +814,11 @@
}); });
finalDemandHints = ''; finalDemandHints = '';
if (demandHintTags.length) { if (demandHintTags.length) {
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
finalDemandHints = '\n<demandhint>\n' + demandHintTags.join('') + '</demandhint>'; finalDemandHints = '\n<demandhint>\n' + demandHintTags.join('') + '</demandhint>';
} }
// make all responsetypes descendants of a single problem element // make all responsetypes descendants of a single problem element
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
finalXml = '<problem>\n' + responseTypesXML.join('\n\n') + finalDemandHints + '\n</problem>'; finalXml = '<problem>\n' + responseTypesXML.join('\n\n') + finalDemandHints + '\n</problem>';
return finalXml; return finalXml;
}; };
......
...@@ -747,7 +747,7 @@ ...@@ -747,7 +747,7 @@
HtmlUtils.setHtml($($spanEl), HtmlUtils.HTML(text.toString())); HtmlUtils.setHtml($($spanEl), HtmlUtils.HTML(text.toString()));
return $spanEl.wrap('<li>').parent()[0]; // safe-lint: disable=javascript-jquery-insertion return $spanEl.wrap('<li>').parent()[0]; // xss-lint: disable=javascript-jquery-insertion
}; };
return AsyncProcess.array(captions, process).done(function(list) { return AsyncProcess.array(captions, process).done(function(list) {
......
...@@ -32,7 +32,7 @@ from django.utils.http import urlquote_plus ...@@ -32,7 +32,7 @@ from django.utils.http import urlquote_plus
<script> <script>
## This JavaScript is being HTML-escaped because it historically has, and it is not clear what ## This JavaScript is being HTML-escaped because it historically has, and it is not clear what
## the correct syntax is. For safety, maintain the previous behavior. ## the correct syntax is. For safety, maintain the previous behavior.
## safe-lint: disable=mako-invalid-js-filter ## xss-lint: disable=mako-invalid-js-filter
${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph", not course.no_grade, not course.no_grade)} ${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph", not course.no_grade, not course.no_grade)}
</script> </script>
</%block> </%block>
......
...@@ -64,27 +64,27 @@ $(function () { ...@@ -64,27 +64,27 @@ $(function () {
categoryData = categories[ section['category'] ] categoryData = categories[ section['category'] ]
## Because this is Python (Mako) embedded in JavaScript, our safe linting script is ## Because this is Python (Mako) embedded in JavaScript, our xss linting script is
## thoroughly confused. We should rewrite this file to remove Python/Mako. ## thoroughly confused. We should rewrite this file to remove Python/Mako.
## safe-lint: disable=javascript-jquery-append ## xss-lint: disable=javascript-jquery-append
categoryData['data'].append( [tickIndex, section['percent']] ) categoryData['data'].append( [tickIndex, section['percent']] )
## Note that some courses had stored images in the Abbreviation. We are no longer ## Note that some courses had stored images in the Abbreviation. We are no longer
## allowing the display of such images, and remove any previously stored HTML ## allowing the display of such images, and remove any previously stored HTML
## to prevent ugly HTML from being shown to learners. ## to prevent ugly HTML from being shown to learners.
## safe-lint: disable=javascript-jquery-append ## xss-lint: disable=javascript-jquery-append
ticks.append( [tickIndex, bleach.clean(section['label'], tags=[], strip=True)] ) ticks.append( [tickIndex, bleach.clean(section['label'], tags=[], strip=True)] )
if section['category'] in detail_tooltips: if section['category'] in detail_tooltips:
## safe-lint: disable=javascript-jquery-append ## xss-lint: disable=javascript-jquery-append
detail_tooltips[ section['category'] ].append( section['detail'] ) detail_tooltips[ section['category'] ].append( section['detail'] )
else: else:
detail_tooltips[ section['category'] ] = [ section['detail'], ] detail_tooltips[ section['category'] ] = [ section['detail'], ]
if 'mark' in section: if 'mark' in section:
## safe-lint: disable=javascript-jquery-append ## xss-lint: disable=javascript-jquery-append
droppedScores.append( [tickIndex, 0.05] ) droppedScores.append( [tickIndex, 0.05] )
## safe-lint: disable=javascript-jquery-append ## xss-lint: disable=javascript-jquery-append
dropped_score_tooltips.append( section['mark']['detail'] ) dropped_score_tooltips.append( section['mark']['detail'] )
tickIndex += 1 tickIndex += 1
...@@ -107,7 +107,7 @@ $(function () { ...@@ -107,7 +107,7 @@ $(function () {
else: else:
color = colors[ extraColorIndex % len(colors) ] color = colors[ extraColorIndex % len(colors) ]
extraColorIndex += 1 extraColorIndex += 1
## safe-lint: disable=javascript-jquery-append ## xss-lint: disable=javascript-jquery-append
series.append({ series.append({
'label' : section['category'] + "-grade_breakdown", 'label' : section['category'] + "-grade_breakdown",
'data' : [ [overviewBarX, section['percent']] ], 'data' : [ [overviewBarX, section['percent']] ],
...@@ -131,7 +131,7 @@ $(function () { ...@@ -131,7 +131,7 @@ $(function () {
descending_grades = sorted(grade_cutoffs, key=lambda x: grade_cutoffs[x], reverse=True) descending_grades = sorted(grade_cutoffs, key=lambda x: grade_cutoffs[x], reverse=True)
for grade in descending_grades: for grade in descending_grades:
percent = grade_cutoffs[grade] percent = grade_cutoffs[grade]
## safe-lint: disable=javascript-jquery-append ## xss-lint: disable=javascript-jquery-append
grade_cutoff_ticks.append( [ percent, u"{0} {1:.0%}".format(grade, percent) ] ) grade_cutoff_ticks.append( [ percent, u"{0} {1:.0%}".format(grade, percent) ] )
else: else:
grade_cutoff_ticks = [ ] grade_cutoff_ticks = [ ]
...@@ -284,7 +284,7 @@ $(function () { ...@@ -284,7 +284,7 @@ $(function () {
edx.HtmlUtils.append( edx.HtmlUtils.append(
$grade_detail_graph, $grade_detail_graph,
edx.HtmlUtils.joinHtml( edx.HtmlUtils.joinHtml(
// safe-lint: disable=javascript-concat-html // xss-lint: disable=javascript-concat-html
edx.HtmlUtils.HTML('<div class="overallGrade" style="position:absolute;left:' + (o.left - 12) + 'px;top:' + (o.top - 20) + 'px">'), edx.HtmlUtils.HTML('<div class="overallGrade" style="position:absolute;left:' + (o.left - 12) + 'px;top:' + (o.top - 20) + 'px">'),
edx.HtmlUtils.HTML('<span class=sr>'), edx.HtmlUtils.HTML('<span class=sr>'),
gettext('Overall Score'), gettext('Overall Score'),
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<option value="flagged">${_("Flagged")}</option> <option value="flagged">${_("Flagged")}</option>
%endif %endif
</select> </select>
## safe-lint: disable=python-parse-error,python-wrap-html ## xss-lint: disable=python-parse-error,python-wrap-html
</label>${"<% if (isDiscussionDivisionEnabled && isPrivilegedUser) { %>" | n, decode.utf8}<label class="forum-nav-filter-cohort"> </label>${"<% if (isDiscussionDivisionEnabled && isPrivilegedUser) { %>" | n, decode.utf8}<label class="forum-nav-filter-cohort">
## Translators: This labels a group menu in forum navigation ## Translators: This labels a group menu in forum navigation
<span class="sr">${_("Group:")}</span> <span class="sr">${_("Group:")}</span>
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<option value="${group['id']}">${group['name']}</option> <option value="${group['id']}">${group['name']}</option>
%endfor %endfor
</select> </select>
## safe-lint: disable=python-parse-error,python-wrap-html ## xss-lint: disable=python-parse-error,python-wrap-html
</label>${"<% } %>" | n, decode.utf8}<label class="forum-nav-sort"> </label>${"<% } %>" | n, decode.utf8}<label class="forum-nav-sort">
## Translators: This labels a sort menu in forum navigation ## Translators: This labels a sort menu in forum navigation
<span class="sr">${_("Sort:")}</span> <span class="sr">${_("Sort:")}</span>
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
}); });
return item.render().el; return item.render().el;
}, this); }, this);
// safe-lint: disable=javascript-jquery-append // xss-lint: disable=javascript-jquery-append
this.$el.find('ol').append(items); this.$el.find('ol').append(items);
}, },
......
...@@ -63,7 +63,7 @@ class TestPaverQualityViolations(unittest.TestCase): ...@@ -63,7 +63,7 @@ class TestPaverQualityViolations(unittest.TestCase):
class TestPaverReportViolationsCounts(unittest.TestCase): class TestPaverReportViolationsCounts(unittest.TestCase):
""" """
For testing utility functions for getting counts from reports for For testing utility functions for getting counts from reports for
run_eslint, run_complexity, run_safelint, and run_safecommit_report. run_eslint, run_complexity, run_xsslint, and run_xsscommitlint.
""" """
def setUp(self): def setUp(self):
...@@ -136,9 +136,9 @@ class TestPaverReportViolationsCounts(unittest.TestCase): ...@@ -136,9 +136,9 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
actual_count = pavelib.quality._get_count_from_last_line(self.f.name, "foo") # pylint: disable=protected-access actual_count = pavelib.quality._get_count_from_last_line(self.f.name, "foo") # pylint: disable=protected-access
self.assertEqual(actual_count, None) self.assertEqual(actual_count, None)
def test_get_safelint_counts_happy(self): def test_get_xsslint_counts_happy(self):
""" """
Test happy path getting violation counts from safelint report. Test happy path getting violation counts from xsslint report.
""" """
report = textwrap.dedent(""" report = textwrap.dedent("""
test.html: 30:53: javascript-jquery-append: $('#test').append(print_tos); test.html: 30:53: javascript-jquery-append: $('#test').append(print_tos);
...@@ -150,7 +150,7 @@ class TestPaverReportViolationsCounts(unittest.TestCase): ...@@ -150,7 +150,7 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
""") """)
with open(self.f.name, 'w') as f: with open(self.f.name, 'w') as f:
f.write(report) f.write(report)
counts = pavelib.quality._get_safelint_counts(self.f.name) # pylint: disable=protected-access counts = pavelib.quality._get_xsslint_counts(self.f.name) # pylint: disable=protected-access
self.assertDictEqual(counts, { self.assertDictEqual(counts, {
'rules': { 'rules': {
'javascript-concat-html': 310, 'javascript-concat-html': 310,
...@@ -159,9 +159,9 @@ class TestPaverReportViolationsCounts(unittest.TestCase): ...@@ -159,9 +159,9 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
'total': 2608, 'total': 2608,
}) })
def test_get_safelint_counts_bad_counts(self): def test_get_xsslint_counts_bad_counts(self):
""" """
Test getting violation counts from truncated and malformed safelint Test getting violation counts from truncated and malformed xsslint
report. report.
""" """
report = textwrap.dedent(""" report = textwrap.dedent("""
...@@ -169,15 +169,15 @@ class TestPaverReportViolationsCounts(unittest.TestCase): ...@@ -169,15 +169,15 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
""") """)
with open(self.f.name, 'w') as f: with open(self.f.name, 'w') as f:
f.write(report) f.write(report)
counts = pavelib.quality._get_safelint_counts(self.f.name) # pylint: disable=protected-access counts = pavelib.quality._get_xsslint_counts(self.f.name) # pylint: disable=protected-access
self.assertDictEqual(counts, { self.assertDictEqual(counts, {
'rules': {}, 'rules': {},
'total': None, 'total': None,
}) })
def test_get_safecommit_count_happy(self): def test_get_xsscommitlint_count_happy(self):
""" """
Test happy path getting violation count from safecommit report. Test happy path getting violation count from xsscommitlint report.
""" """
report = textwrap.dedent(""" report = textwrap.dedent("""
Linting lms/templates/navigation.html: Linting lms/templates/navigation.html:
...@@ -190,26 +190,26 @@ class TestPaverReportViolationsCounts(unittest.TestCase): ...@@ -190,26 +190,26 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
""") """)
with open(self.f.name, 'w') as f: with open(self.f.name, 'w') as f:
f.write(report) f.write(report)
count = pavelib.quality._get_safecommit_count(self.f.name) # pylint: disable=protected-access count = pavelib.quality._get_xsscommitlint_count(self.f.name) # pylint: disable=protected-access
self.assertEqual(count, 5) self.assertEqual(count, 5)
def test_get_safecommit_count_bad_counts(self): def test_get_xsscommitlint_count_bad_counts(self):
""" """
Test getting violation count from truncated safecommit report. Test getting violation count from truncated xsscommitlint report.
""" """
report = textwrap.dedent(""" report = textwrap.dedent("""
Linting lms/templates/navigation.html: Linting lms/templates/navigation.html:
""") """)
with open(self.f.name, 'w') as f: with open(self.f.name, 'w') as f:
f.write(report) f.write(report)
count = pavelib.quality._get_safecommit_count(self.f.name) # pylint: disable=protected-access count = pavelib.quality._get_xsscommitlint_count(self.f.name) # pylint: disable=protected-access
self.assertIsNone(count) self.assertIsNone(count)
def test_get_safecommit_count_no_files(self): def test_get_xsscommitlint_count_no_files(self):
""" """
Test getting violation count from safecommit report where no files were Test getting violation count from xsscommitlint report where no files were
linted. linted.
""" """
report = textwrap.dedent(""" report = textwrap.dedent("""
...@@ -217,7 +217,7 @@ class TestPaverReportViolationsCounts(unittest.TestCase): ...@@ -217,7 +217,7 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
""") """)
with open(self.f.name, 'w') as f: with open(self.f.name, 'w') as f:
f.write(report) f.write(report)
count = pavelib.quality._get_safecommit_count(self.f.name) # pylint: disable=protected-access count = pavelib.quality._get_xsscommitlint_count(self.f.name) # pylint: disable=protected-access
self.assertEqual(count, 0) self.assertEqual(count, 0)
......
""" """
Tests for paver safecommit quality tasks Tests for paver xsscommitlint quality tasks
""" """
from mock import patch from mock import patch
from paver.easy import call_task from paver.easy import call_task
...@@ -9,36 +9,36 @@ import pavelib.quality ...@@ -9,36 +9,36 @@ import pavelib.quality
from .utils import PaverTestCase from .utils import PaverTestCase
class PaverSafeCommitTest(PaverTestCase): class PaverXSSCommitLintTest(PaverTestCase):
""" """
Test run_safecommit_report with a mocked environment in order to pass in Test run_xsscommitlint with a mocked environment in order to pass in
opts. opts.
""" """
def setUp(self): def setUp(self):
super(PaverSafeCommitTest, self).setUp() super(PaverXSSCommitLintTest, self).setUp()
self.reset_task_messages() self.reset_task_messages()
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safecommit_count') @patch.object(pavelib.quality, '_get_xsscommitlint_count')
def test_safecommit_violation_number_not_found(self, _mock_count, _mock_report_dir, _mock_write_metric): def test_xsscommitlint_violation_number_not_found(self, _mock_count, _mock_report_dir, _mock_write_metric):
""" """
run_safecommit_report encounters an error parsing the safecommit output run_xsscommitlint encounters an error parsing the xsscommitlint output
log. log.
""" """
_mock_count.return_value = None _mock_count.return_value = None
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
call_task('pavelib.quality.run_safecommit_report') call_task('pavelib.quality.run_xsscommitlint')
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safecommit_count') @patch.object(pavelib.quality, '_get_xsscommitlint_count')
def test_safecommit_vanilla(self, _mock_count, _mock_report_dir, _mock_write_metric): def test_xsscommitlint_vanilla(self, _mock_count, _mock_report_dir, _mock_write_metric):
""" """
run_safecommit_report finds violations. run_xsscommitlint finds violations.
""" """
_mock_count.return_value = 0 _mock_count.return_value = 0
call_task('pavelib.quality.run_safecommit_report') call_task('pavelib.quality.run_xsscommitlint')
""" """
Tests for paver safelint quality tasks Tests for paver xsslint quality tasks
""" """
from mock import patch from mock import patch
from paver.easy import call_task from paver.easy import call_task
...@@ -9,110 +9,110 @@ import pavelib.quality ...@@ -9,110 +9,110 @@ import pavelib.quality
from .utils import PaverTestCase from .utils import PaverTestCase
class PaverSafeLintTest(PaverTestCase): class PaverXSSLintTest(PaverTestCase):
""" """
Test run_safelint with a mocked environment in order to pass in opts Test run_xsslint with a mocked environment in order to pass in opts
""" """
def setUp(self): def setUp(self):
super(PaverSafeLintTest, self).setUp() super(PaverXSSLintTest, self).setUp()
self.reset_task_messages() self.reset_task_messages()
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts') @patch.object(pavelib.quality, '_get_xsslint_counts')
def test_safelint_violation_number_not_found(self, _mock_counts, _mock_report_dir, _mock_write_metric): def test_xsslint_violation_number_not_found(self, _mock_counts, _mock_report_dir, _mock_write_metric):
""" """
run_safelint encounters an error parsing the safelint output log run_xsslint encounters an error parsing the xsslint output log
""" """
_mock_counts.return_value = {} _mock_counts.return_value = {}
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
call_task('pavelib.quality.run_safelint') call_task('pavelib.quality.run_xsslint')
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts') @patch.object(pavelib.quality, '_get_xsslint_counts')
def test_safelint_vanilla(self, _mock_counts, _mock_report_dir, _mock_write_metric): def test_xsslint_vanilla(self, _mock_counts, _mock_report_dir, _mock_write_metric):
""" """
run_safelint finds violations, but a limit was not set run_xsslint finds violations, but a limit was not set
""" """
_mock_counts.return_value = {'total': 0} _mock_counts.return_value = {'total': 0}
call_task('pavelib.quality.run_safelint') call_task('pavelib.quality.run_xsslint')
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts') @patch.object(pavelib.quality, '_get_xsslint_counts')
def test_safelint_invalid_thresholds_option(self, _mock_counts, _mock_report_dir, _mock_write_metric): def test_xsslint_invalid_thresholds_option(self, _mock_counts, _mock_report_dir, _mock_write_metric):
""" """
run_safelint fails when thresholds option is poorly formatted run_xsslint fails when thresholds option is poorly formatted
""" """
_mock_counts.return_value = {'total': 0} _mock_counts.return_value = {'total': 0}
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
call_task('pavelib.quality.run_safelint', options={"thresholds": "invalid"}) call_task('pavelib.quality.run_xsslint', options={"thresholds": "invalid"})
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts') @patch.object(pavelib.quality, '_get_xsslint_counts')
def test_safelint_invalid_thresholds_option_key(self, _mock_counts, _mock_report_dir, _mock_write_metric): def test_xsslint_invalid_thresholds_option_key(self, _mock_counts, _mock_report_dir, _mock_write_metric):
""" """
run_safelint fails when thresholds option is poorly formatted run_xsslint fails when thresholds option is poorly formatted
""" """
_mock_counts.return_value = {'total': 0} _mock_counts.return_value = {'total': 0}
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
call_task('pavelib.quality.run_safelint', options={"thresholds": '{"invalid": 3}'}) call_task('pavelib.quality.run_xsslint', options={"thresholds": '{"invalid": 3}'})
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts') @patch.object(pavelib.quality, '_get_xsslint_counts')
def test_safelint_too_many_violations(self, _mock_counts, _mock_report_dir, _mock_write_metric): def test_xsslint_too_many_violations(self, _mock_counts, _mock_report_dir, _mock_write_metric):
""" """
run_safelint finds more violations than are allowed run_xsslint finds more violations than are allowed
""" """
_mock_counts.return_value = {'total': 4} _mock_counts.return_value = {'total': 4}
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
call_task('pavelib.quality.run_safelint', options={"thresholds": '{"total": 3}'}) call_task('pavelib.quality.run_xsslint', options={"thresholds": '{"total": 3}'})
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts') @patch.object(pavelib.quality, '_get_xsslint_counts')
def test_safelint_under_limit(self, _mock_counts, _mock_report_dir, _mock_write_metric): def test_xsslint_under_limit(self, _mock_counts, _mock_report_dir, _mock_write_metric):
""" """
run_safelint finds fewer violations than are allowed run_xsslint finds fewer violations than are allowed
""" """
_mock_counts.return_value = {'total': 4} _mock_counts.return_value = {'total': 4}
# No System Exit is expected # No System Exit is expected
call_task('pavelib.quality.run_safelint', options={"thresholds": '{"total": 5}'}) call_task('pavelib.quality.run_xsslint', options={"thresholds": '{"total": 5}'})
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts') @patch.object(pavelib.quality, '_get_xsslint_counts')
def test_safelint_rule_violation_number_not_found(self, _mock_counts, _mock_report_dir, _mock_write_metric): def test_xsslint_rule_violation_number_not_found(self, _mock_counts, _mock_report_dir, _mock_write_metric):
""" """
run_safelint encounters an error parsing the safelint output log for a run_xsslint encounters an error parsing the xsslint output log for a
given rule threshold that was set. given rule threshold that was set.
""" """
_mock_counts.return_value = {'total': 4} _mock_counts.return_value = {'total': 4}
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
call_task('pavelib.quality.run_safelint', options={"thresholds": '{"rules": {"javascript-escape": 3}}'}) call_task('pavelib.quality.run_xsslint', options={"thresholds": '{"rules": {"javascript-escape": 3}}'})
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts') @patch.object(pavelib.quality, '_get_xsslint_counts')
def test_safelint_too_many_rule_violations(self, _mock_counts, _mock_report_dir, _mock_write_metric): def test_xsslint_too_many_rule_violations(self, _mock_counts, _mock_report_dir, _mock_write_metric):
""" """
run_safelint finds more rule violations than are allowed run_xsslint finds more rule violations than are allowed
""" """
_mock_counts.return_value = {'total': 4, 'rules': {'javascript-escape': 4}} _mock_counts.return_value = {'total': 4, 'rules': {'javascript-escape': 4}}
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
call_task('pavelib.quality.run_safelint', options={"thresholds": '{"rules": {"javascript-escape": 3}}'}) call_task('pavelib.quality.run_xsslint', options={"thresholds": '{"rules": {"javascript-escape": 3}}'})
@patch.object(pavelib.quality, '_write_metric') @patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir') @patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts') @patch.object(pavelib.quality, '_get_xsslint_counts')
def test_safelint_under_rule_limit(self, _mock_counts, _mock_report_dir, _mock_write_metric): def test_xsslint_under_rule_limit(self, _mock_counts, _mock_report_dir, _mock_write_metric):
""" """
run_safelint finds fewer rule violations than are allowed run_xsslint finds fewer rule violations than are allowed
""" """
_mock_counts.return_value = {'total': 4, 'rules': {'javascript-escape': 4}} _mock_counts.return_value = {'total': 4, 'rules': {'javascript-escape': 4}}
# No System Exit is expected # No System Exit is expected
call_task('pavelib.quality.run_safelint', options={"thresholds": '{"rules": {"javascript-escape": 5}}'}) call_task('pavelib.quality.run_xsslint', options={"thresholds": '{"rules": {"javascript-escape": 5}}'})
...@@ -321,9 +321,9 @@ def run_eslint(options): ...@@ -321,9 +321,9 @@ def run_eslint(options):
("thresholds=", "t", "json containing limit for number of acceptable violations per rule"), ("thresholds=", "t", "json containing limit for number of acceptable violations per rule"),
]) ])
@timed @timed
def run_safelint(options): def run_xsslint(options):
""" """
Runs safe_template_linter.py on the codebase Runs xss_linter.py on the codebase
""" """
thresholds_option = getattr(options, 'thresholds', '{}') thresholds_option = getattr(options, 'thresholds', '{}')
...@@ -342,42 +342,42 @@ def run_safelint(options): ...@@ -342,42 +342,42 @@ def run_safelint(options):
) )
) )
safelint_script = "safe_template_linter.py" xsslint_script = "xss_linter.py"
safelint_report_dir = (Env.REPORT_DIR / "safelint") xsslint_report_dir = (Env.REPORT_DIR / "xsslint")
safelint_report = safelint_report_dir / "safelint.report" xsslint_report = xsslint_report_dir / "xsslint.report"
_prepare_report_dir(safelint_report_dir) _prepare_report_dir(xsslint_report_dir)
sh( sh(
"{repo_root}/scripts/{safelint_script} --rule-totals >> {safelint_report}".format( "{repo_root}/scripts/{xsslint_script} --rule-totals >> {xsslint_report}".format(
repo_root=Env.REPO_ROOT, repo_root=Env.REPO_ROOT,
safelint_script=safelint_script, xsslint_script=xsslint_script,
safelint_report=safelint_report, xsslint_report=xsslint_report,
), ),
ignore_error=True ignore_error=True
) )
safelint_counts = _get_safelint_counts(safelint_report) xsslint_counts = _get_xsslint_counts(xsslint_report)
try: try:
metrics_str = "Number of {safelint_script} violations: {num_violations}\n".format( metrics_str = "Number of {xsslint_script} violations: {num_violations}\n".format(
safelint_script=safelint_script, num_violations=int(safelint_counts['total']) xsslint_script=xsslint_script, num_violations=int(xsslint_counts['total'])
) )
if 'rules' in safelint_counts and any(safelint_counts['rules']): if 'rules' in xsslint_counts and any(xsslint_counts['rules']):
metrics_str += "\n" metrics_str += "\n"
rule_keys = sorted(safelint_counts['rules'].keys()) rule_keys = sorted(xsslint_counts['rules'].keys())
for rule in rule_keys: for rule in rule_keys:
metrics_str += "{rule} violations: {count}\n".format( metrics_str += "{rule} violations: {count}\n".format(
rule=rule, rule=rule,
count=int(safelint_counts['rules'][rule]) count=int(xsslint_counts['rules'][rule])
) )
except TypeError: except TypeError:
raise BuildFailure( raise BuildFailure(
"Error. Number of {safelint_script} violations could not be found in {safelint_report}".format( "Error. Number of {xsslint_script} violations could not be found in {xsslint_report}".format(
safelint_script=safelint_script, safelint_report=safelint_report xsslint_script=xsslint_script, xsslint_report=xsslint_report
) )
) )
metrics_report = (Env.METRICS_DIR / "safelint") metrics_report = (Env.METRICS_DIR / "xsslint")
# Record the metric # Record the metric
_write_metric(metrics_str, metrics_report) _write_metric(metrics_str, metrics_report)
# Print number of violations to log. # Print number of violations to log.
...@@ -387,35 +387,35 @@ def run_safelint(options): ...@@ -387,35 +387,35 @@ def run_safelint(options):
# Test total violations against threshold. # Test total violations against threshold.
if 'total' in violation_thresholds.keys(): if 'total' in violation_thresholds.keys():
if violation_thresholds['total'] < safelint_counts['total']: if violation_thresholds['total'] < xsslint_counts['total']:
error_message = "Too many violations total ({count}).\nThe limit is {violations_limit}.".format( error_message = "Too many violations total ({count}).\nThe limit is {violations_limit}.".format(
count=safelint_counts['total'], violations_limit=violation_thresholds['total'] count=xsslint_counts['total'], violations_limit=violation_thresholds['total']
) )
# Test rule violations against thresholds. # Test rule violations against thresholds.
if 'rules' in violation_thresholds: if 'rules' in violation_thresholds:
threshold_keys = sorted(violation_thresholds['rules'].keys()) threshold_keys = sorted(violation_thresholds['rules'].keys())
for threshold_key in threshold_keys: for threshold_key in threshold_keys:
if threshold_key not in safelint_counts['rules']: if threshold_key not in xsslint_counts['rules']:
error_message += ( error_message += (
"\nNumber of {safelint_script} violations for {rule} could not be found in " "\nNumber of {xsslint_script} violations for {rule} could not be found in "
"{safelint_report}." "{xsslint_report}."
).format( ).format(
safelint_script=safelint_script, rule=threshold_key, safelint_report=safelint_report xsslint_script=xsslint_script, rule=threshold_key, xsslint_report=xsslint_report
) )
elif violation_thresholds['rules'][threshold_key] < safelint_counts['rules'][threshold_key]: elif violation_thresholds['rules'][threshold_key] < xsslint_counts['rules'][threshold_key]:
error_message += \ error_message += \
"\nToo many {rule} violations ({count}).\nThe {rule} limit is {violations_limit}.".format( "\nToo many {rule} violations ({count}).\nThe {rule} limit is {violations_limit}.".format(
rule=threshold_key, count=safelint_counts['rules'][threshold_key], rule=threshold_key, count=xsslint_counts['rules'][threshold_key],
violations_limit=violation_thresholds['rules'][threshold_key], violations_limit=violation_thresholds['rules'][threshold_key],
) )
if error_message is not "": if error_message is not "":
raise BuildFailure( raise BuildFailure(
"SafeTemplateLinter Failed.\n{error_message}\n" "XSSLinter Failed.\n{error_message}\n"
"See {safelint_report} or run the following command to hone in on the problem:\n" "See {xsslint_report} or run the following command to hone in on the problem:\n"
" ./scripts/safe-commit-linter.sh -h".format( " ./scripts/xss-commit-linter.sh -h".format(
error_message=error_message, safelint_report=safelint_report error_message=error_message, xsslint_report=xsslint_report
) )
) )
...@@ -423,42 +423,42 @@ def run_safelint(options): ...@@ -423,42 +423,42 @@ def run_safelint(options):
@task @task
@needs('pavelib.prereqs.install_python_prereqs') @needs('pavelib.prereqs.install_python_prereqs')
@timed @timed
def run_safecommit_report(): def run_xsscommitlint():
""" """
Runs safe-commit-linter.sh on the current branch. Runs xss-commit-linter.sh on the current branch.
""" """
safecommit_script = "safe-commit-linter.sh" xsscommitlint_script = "xss-commit-linter.sh"
safecommit_report_dir = (Env.REPORT_DIR / "safecommit") xsscommitlint_report_dir = (Env.REPORT_DIR / "xsscommitlint")
safecommit_report = safecommit_report_dir / "safecommit.report" xsscommitlint_report = xsscommitlint_report_dir / "xsscommitlint.report"
_prepare_report_dir(safecommit_report_dir) _prepare_report_dir(xsscommitlint_report_dir)
sh( sh(
"{repo_root}/scripts/{safecommit_script} | tee {safecommit_report}".format( "{repo_root}/scripts/{xsscommitlint_script} | tee {xsscommitlint_report}".format(
repo_root=Env.REPO_ROOT, repo_root=Env.REPO_ROOT,
safecommit_script=safecommit_script, xsscommitlint_script=xsscommitlint_script,
safecommit_report=safecommit_report, xsscommitlint_report=xsscommitlint_report,
), ),
ignore_error=True ignore_error=True
) )
safecommit_count = _get_safecommit_count(safecommit_report) xsscommitlint_count = _get_xsscommitlint_count(xsscommitlint_report)
try: try:
num_violations = int(safecommit_count) num_violations = int(xsscommitlint_count)
except TypeError: except TypeError:
raise BuildFailure( raise BuildFailure(
"Error. Number of {safecommit_script} violations could not be found in {safecommit_report}".format( "Error. Number of {xsscommitlint_script} violations could not be found in {xsscommitlint_report}".format(
safecommit_script=safecommit_script, safecommit_report=safecommit_report xsscommitlint_script=xsscommitlint_script, xsscommitlint_report=xsscommitlint_report
) )
) )
# Print number of violations to log. # Print number of violations to log.
violations_count_str = "Number of {safecommit_script} violations: {num_violations}\n".format( violations_count_str = "Number of {xsscommitlint_script} violations: {num_violations}\n".format(
safecommit_script=safecommit_script, num_violations=num_violations xsscommitlint_script=xsscommitlint_script, num_violations=num_violations
) )
# Record the metric # Record the metric
metrics_report = (Env.METRICS_DIR / "safecommit") metrics_report = (Env.METRICS_DIR / "xsscommitlint")
_write_metric(violations_count_str, metrics_report) _write_metric(violations_count_str, metrics_report)
# Output report to console. # Output report to console.
sh("cat {metrics_report}".format(metrics_report=metrics_report), ignore_error=True) sh("cat {metrics_report}".format(metrics_report=metrics_report), ignore_error=True)
...@@ -534,12 +534,12 @@ def _get_count_from_last_line(filename, file_type): ...@@ -534,12 +534,12 @@ def _get_count_from_last_line(filename, file_type):
return None return None
def _get_safelint_counts(filename): def _get_xsslint_counts(filename):
""" """
This returns a dict of violations from the safelint report. This returns a dict of violations from the xsslint report.
Arguments: Arguments:
filename: The name of the safelint report. filename: The name of the xsslint report.
Returns: Returns:
A dict containing the following: A dict containing the following:
...@@ -566,15 +566,15 @@ def _get_safelint_counts(filename): ...@@ -566,15 +566,15 @@ def _get_safelint_counts(filename):
return violations return violations
def _get_safecommit_count(filename): def _get_xsscommitlint_count(filename):
""" """
Returns the violation count from the safecommit report. Returns the violation count from the xsscommitlint report.
Arguments: Arguments:
filename: The name of the safecommit report. filename: The name of the xsscommitlint report.
Returns: Returns:
The count of safecommit violations, or None if there is a problem. The count of xsscommitlint violations, or None if there is a problem.
""" """
report_contents = _get_report_contents(filename) report_contents = _get_report_contents(filename)
......
...@@ -14,8 +14,8 @@ set -e ...@@ -14,8 +14,8 @@ set -e
export PYLINT_THRESHOLD=3600 export PYLINT_THRESHOLD=3600
export ESLINT_THRESHOLD=10122 export ESLINT_THRESHOLD=10122
SAFELINT_THRESHOLDS=`cat scripts/safelint_thresholds.json` XSSLINT_THRESHOLDS=`cat scripts/xsslint_thresholds.json`
export SAFELINT_THRESHOLDS=${SAFELINT_THRESHOLDS//[[:space:]]/} export XSSLINT_THRESHOLDS=${XSSLINT_THRESHOLDS//[[:space:]]/}
doCheckVars() { doCheckVars() {
if [ -n "$CIRCLECI" ] ; then if [ -n "$CIRCLECI" ] ; then
......
...@@ -84,10 +84,10 @@ case "$TEST_SUITE" in ...@@ -84,10 +84,10 @@ case "$TEST_SUITE" in
paver run_eslint -l $ESLINT_THRESHOLD > eslint.log || { cat eslint.log; EXIT=1; } paver run_eslint -l $ESLINT_THRESHOLD > eslint.log || { cat eslint.log; EXIT=1; }
echo "Running code complexity report (python)." echo "Running code complexity report (python)."
paver run_complexity || echo "Unable to calculate code complexity. Ignoring error." paver run_complexity || echo "Unable to calculate code complexity. Ignoring error."
echo "Running safe template linter report." echo "Running xss linter report."
paver run_safelint -t $SAFELINT_THRESHOLDS > safelint.log || { cat safelint.log; EXIT=1; } paver run_xsslint -t $XSSLINT_THRESHOLDS > xsslint.log || { cat xsslint.log; EXIT=1; }
echo "Running safe commit linter report." echo "Running xss commit linter report."
paver run_safecommit_report > safecommit.log || { cat safecommit.log; EXIT=1; } paver run_xsscommitlint > xsscommitlint.log || { cat xsscommitlint.log; EXIT=1; }
# Run quality task. Pass in the 'fail-under' percentage to diff-quality # Run quality task. Pass in the 'fail-under' percentage to diff-quality
echo "Running diff quality." echo "Running diff quality."
paver run_quality -p 100 || EXIT=1 paver run_quality -p 100 || EXIT=1
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
Tests for safe_template_linter.py Tests for xss_linter.py
""" """
import re import re
import textwrap import textwrap
...@@ -10,7 +10,7 @@ from unittest import TestCase ...@@ -10,7 +10,7 @@ from unittest import TestCase
import mock import mock
from ddt import data, ddt from ddt import data, ddt
from scripts.safe_template_linter import ( from scripts.xss_linter import (
FileResults, FileResults,
JavaScriptLinter, JavaScriptLinter,
MakoTemplateLinter, MakoTemplateLinter,
...@@ -93,7 +93,7 @@ class TestLinter(TestCase): ...@@ -93,7 +93,7 @@ class TestLinter(TestCase):
self.assertEqual(violation.rule, rule) self.assertEqual(violation.rule, rule)
class TestSafeTemplateLinter(TestCase): class TestXSSLinter(TestCase):
""" """
Test some top-level linter functions Test some top-level linter functions
""" """
...@@ -107,7 +107,7 @@ class TestSafeTemplateLinter(TestCase): ...@@ -107,7 +107,7 @@ class TestSafeTemplateLinter(TestCase):
self.patch_is_valid_directory(UnderscoreTemplateLinter) self.patch_is_valid_directory(UnderscoreTemplateLinter)
self.patch_is_valid_directory(PythonLinter) self.patch_is_valid_directory(PythonLinter)
patcher = mock.patch('scripts.safe_template_linter.is_skip_dir', return_value=False) patcher = mock.patch('scripts.xss_linter.is_skip_dir', return_value=False)
patcher.start() patcher.start()
self.addCleanup(patcher.stop) self.addCleanup(patcher.stop)
...@@ -548,7 +548,7 @@ class TestMakoTemplateLinter(TestLinter): ...@@ -548,7 +548,7 @@ class TestMakoTemplateLinter(TestLinter):
# This is anything but a Mako file. # This is anything but a Mako file.
# pragma can appear anywhere in file # pragma can appear anywhere in file
# safe-lint: disable=mako-missing-default # xss-lint: disable=mako-missing-default
""") """)
linter._check_mako_file_is_safe(mako_template, results) linter._check_mako_file_is_safe(mako_template, results)
...@@ -566,7 +566,7 @@ class TestMakoTemplateLinter(TestLinter): ...@@ -566,7 +566,7 @@ class TestMakoTemplateLinter(TestLinter):
mako_template = textwrap.dedent(""" mako_template = textwrap.dedent("""
<%page expression_filter="h"/> <%page expression_filter="h"/>
## safe-lint: disable=mako-unwanted-html-filter ## xss-lint: disable=mako-unwanted-html-filter
${x | h} ${x | h}
""") """)
...@@ -982,25 +982,25 @@ class TestUnderscoreTemplateLinter(TestLinter): ...@@ -982,25 +982,25 @@ class TestUnderscoreTemplateLinter(TestLinter):
@data( @data(
{ {
'template': 'template':
'<% // safe-lint: disable=underscore-not-escaped %>\n' '<% // xss-lint: disable=underscore-not-escaped %>\n'
'<%= message %>', '<%= message %>',
'is_disabled': [True], 'is_disabled': [True],
}, },
{ {
'template': 'template':
'<% // safe-lint: disable=another-rule,underscore-not-escaped %>\n' '<% // xss-lint: disable=another-rule,underscore-not-escaped %>\n'
'<%= message %>', '<%= message %>',
'is_disabled': [True], 'is_disabled': [True],
}, },
{ {
'template': 'template':
'<% // safe-lint: disable=another-rule %>\n' '<% // xss-lint: disable=another-rule %>\n'
'<%= message %>', '<%= message %>',
'is_disabled': [False], 'is_disabled': [False],
}, },
{ {
'template': 'template':
'<% // safe-lint: disable=underscore-not-escaped %>\n' '<% // xss-lint: disable=underscore-not-escaped %>\n'
'<%= message %>\n' '<%= message %>\n'
'<%= message %>', '<%= message %>',
'is_disabled': [True, False], 'is_disabled': [True, False],
...@@ -1010,22 +1010,22 @@ class TestUnderscoreTemplateLinter(TestLinter): ...@@ -1010,22 +1010,22 @@ class TestUnderscoreTemplateLinter(TestLinter):
'// This test does not use proper Underscore.js Template syntax\n' '// This test does not use proper Underscore.js Template syntax\n'
'// But, it is just testing that a maximum of 5 non-whitespace\n' '// But, it is just testing that a maximum of 5 non-whitespace\n'
'// are used to designate start of line for disabling the next line.\n' '// are used to designate start of line for disabling the next line.\n'
' 1 2 3 4 5 safe-lint: disable=underscore-not-escaped %>\n' ' 1 2 3 4 5 xss-lint: disable=underscore-not-escaped %>\n'
'<%= message %>\n' '<%= message %>\n'
' 1 2 3 4 5 6 safe-lint: disable=underscore-not-escaped %>\n' ' 1 2 3 4 5 6 xss-lint: disable=underscore-not-escaped %>\n'
'<%= message %>', '<%= message %>',
'is_disabled': [True, False], 'is_disabled': [True, False],
}, },
{ {
'template': 'template':
'<%= message %><% // safe-lint: disable=underscore-not-escaped %>\n' '<%= message %><% // xss-lint: disable=underscore-not-escaped %>\n'
'<%= message %>', '<%= message %>',
'is_disabled': [True, False], 'is_disabled': [True, False],
}, },
{ {
'template': 'template':
'<%= message %>\n' '<%= message %>\n'
'<% // safe-lint: disable=underscore-not-escaped %>', '<% // xss-lint: disable=underscore-not-escaped %>',
'is_disabled': [False], 'is_disabled': [False],
}, },
) )
...@@ -1052,7 +1052,7 @@ class TestUnderscoreTemplateLinter(TestLinter): ...@@ -1052,7 +1052,7 @@ class TestUnderscoreTemplateLinter(TestLinter):
results = FileResults('') results = FileResults('')
template = textwrap.dedent(""" template = textwrap.dedent("""
<% // safe-lint: disable=underscore-not-escaped %> <% // xss-lint: disable=underscore-not-escaped %>
<%= message %> <%= message %>
<%= message %> <%= message %>
""") """)
......
...@@ -3,16 +3,15 @@ set -e ...@@ -3,16 +3,15 @@ set -e
############################################################################### ###############################################################################
# #
# safe-commit-linter.sh # xss-commit-linter.sh
# #
# Executes safe_template_linter.py on the set of files in a particular git # Executes xss_linter.py on the set of files in a particular git commit.
# commit.
# #
############################################################################### ###############################################################################
show_help() { show_help() {
echo "Usage: safe-commit-linter.sh [OPTION]" echo "Usage: xss-commit-linter.sh [OPTION]"
echo "Runs the Safe Template Linter against all files in a git commit." echo "Runs the XSS Linter against all files in a git commit."
echo "" echo ""
echo "Mandatory arguments to long options are mandatory for short options too." echo "Mandatory arguments to long options are mandatory for short options too."
echo " -h, --help Output this help." echo " -h, --help Output this help."
...@@ -24,10 +23,10 @@ show_help() { ...@@ -24,10 +23,10 @@ show_help() {
echo "This scripts does not give a grand total. Be sure to check for" echo "This scripts does not give a grand total. Be sure to check for"
echo "0 violations on each file." echo "0 violations on each file."
echo "" echo ""
echo "For more help using the safe template linter, including details on how" echo "For more help using the xss linter, including details on how to"
echo "to understand and fix any violations, read the docs here:" echo "understand and fix any violations, read the docs here:"
echo "" echo ""
echo " http://edx.readthedocs.org/projects/edx-developer-guide/en/latest/conventions/safe_templates.html#safe-template-linter" echo " http://edx.readthedocs.org/projects/edx-developer-guide/en/latest/conventions/preventing_xss.html#xss-linter"
} }
...@@ -83,6 +82,6 @@ else ...@@ -83,6 +82,6 @@ else
for f in $diff_files; do for f in $diff_files; do
echo "" echo ""
echo "Linting $f:" echo "Linting $f:"
./scripts/safe_template_linter.py $f ./scripts/xss_linter.py $f
done done
fi fi
#!/usr/bin/env python #!/usr/bin/env python
""" """
A linting tool to check if templates are safe A linting tool to check for xss vulnerabilities.
""" """
from __future__ import print_function from __future__ import print_function
...@@ -192,7 +192,7 @@ class Rules(Enum): ...@@ -192,7 +192,7 @@ class Rules(Enum):
An Enum of each rule which the linter will check. An Enum of each rule which the linter will check.
""" """
# IMPORTANT: Do not edit without also updating the docs: # IMPORTANT: Do not edit without also updating the docs:
# - http://edx.readthedocs.io/projects/edx-developer-guide/en/latest/conventions/safe_templates.html#safe-template-linter # - http://edx.readthedocs.org/projects/edx-developer-guide/en/latest/conventions/preventing_xss.html#xss-linter
mako_missing_default = 'mako-missing-default' mako_missing_default = 'mako-missing-default'
mako_multiple_page_tags = 'mako-multiple-page-tags' mako_multiple_page_tags = 'mako-multiple-page-tags'
mako_unparseable_expression = 'mako-unparseable-expression' mako_unparseable_expression = 'mako-unparseable-expression'
...@@ -300,7 +300,7 @@ class RuleViolation(object): ...@@ -300,7 +300,7 @@ class RuleViolation(object):
Pragma format:: Pragma format::
safe-lint: disable=violation-name,other-violation-name xss-lint: disable=violation-name,other-violation-name
Arguments: Arguments:
string: The string of code in which to search for the pragma. string: The string of code in which to search for the pragma.
...@@ -314,7 +314,7 @@ class RuleViolation(object): ...@@ -314,7 +314,7 @@ class RuleViolation(object):
found. found.
""" """
pragma_match = re.search(r'safe-lint:\s*disable=([a-zA-Z,-]+)', string) pragma_match = re.search(r'xss-lint:\s*disable=([a-zA-Z,-]+)', string)
if pragma_match is None: if pragma_match is None:
return return
if scope_start_string: if scope_start_string:
...@@ -398,14 +398,14 @@ class ExpressionRuleViolation(RuleViolation): ...@@ -398,14 +398,14 @@ class ExpressionRuleViolation(RuleViolation):
Pragma format:: Pragma format::
safe-lint: disable=violation-name,other-violation-name xss-lint: disable=violation-name,other-violation-name
Examples:: Examples::
<% // safe-lint: disable=underscore-not-escaped %> <% // xss-lint: disable=underscore-not-escaped %>
<%= gettext('Single Line') %> <%= gettext('Single Line') %>
<%= gettext('Single Line') %><% // safe-lint: disable=underscore-not-escaped %> <%= gettext('Single Line') %><% // xss-lint: disable=underscore-not-escaped %>
Arguments: Arguments:
string_lines: A StringLines containing the contents of the file in string_lines: A StringLines containing the contents of the file in
...@@ -1421,7 +1421,7 @@ class JavaScriptLinter(BaseLinter): ...@@ -1421,7 +1421,7 @@ class JavaScriptLinter(BaseLinter):
class BaseVisitor(ast.NodeVisitor): class BaseVisitor(ast.NodeVisitor):
""" """
Base class for AST NodeVisitor used for Python safe linting. Base class for AST NodeVisitor used for Python xss linting.
Important: This base visitor skips all __repr__ function definitions. Important: This base visitor skips all __repr__ function definitions.
""" """
...@@ -1787,7 +1787,7 @@ class PythonLinter(BaseLinter): ...@@ -1787,7 +1787,7 @@ class PythonLinter(BaseLinter):
if file_name.lower().endswith('tests.py'): if file_name.lower().endswith('tests.py'):
return results return results
# skip this linter code (i.e. safe_template_linter.py) # skip this linter code (i.e. xss_linter.py)
if file_name == os.path.basename(__file__): if file_name == os.path.basename(__file__):
return results return results
...@@ -2493,6 +2493,7 @@ SKIP_DIRS = ( ...@@ -2493,6 +2493,7 @@ SKIP_DIRS = (
'.git', '.git',
'.pycharm_helpers', '.pycharm_helpers',
'common/static/xmodule/modules', 'common/static/xmodule/modules',
'common/static/bundles',
'perf_tests', 'perf_tests',
'node_modules', 'node_modules',
'reports/diff_quality', 'reports/diff_quality',
...@@ -2615,11 +2616,11 @@ def main(): ...@@ -2615,11 +2616,11 @@ def main():
Prints all violations. Prints all violations.
""" """
epilog = "For more help using the safe template linter, including details on how\n" epilog = "For more help using the xss linter, including details on how to\n"
epilog += "to understand and fix any violations, read the docs here:\n" epilog += "understand and fix any violations, read the docs here:\n"
epilog += "\n" epilog += "\n"
# pylint: disable=line-too-long # pylint: disable=line-too-long
epilog += " http://edx.readthedocs.org/projects/edx-developer-guide/en/latest/conventions/safe_templates.html#safe-template-linter\n" epilog += " http://edx.readthedocs.org/projects/edx-developer-guide/en/latest/conventions/preventing_xss.html#xss-linter\n"
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
......
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