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
updateHtml: function(element, html) {
// Replace the element with the new HTML content, rather than adding
// 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({
......
......@@ -344,7 +344,7 @@
for (i = 0; i < options.length; i += 1) {
inner = /\s*\|\|(.*?)\|\|/.exec(options[i]);
if (inner) {
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
demandhints += ' <hint>' + inner[1].trim() + '</hint>\n';
}
}
......@@ -601,9 +601,9 @@
hintLine = '';
if (textHint.hint) {
firstAnswer = textHint.nothint;
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
hintLine = ' <correcthint' + textHint.labelassign + '>' +
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
textHint.hint + '</correcthint>\n';
}
......@@ -611,16 +611,16 @@
if (isRangeToleranceCase(firstAnswer)) {
// [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
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
numericalResponseString = '<numericalresponse answer="' + firstAnswer + '">\n';
} else {
answerData = getAnswerData(firstAnswer);
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
numericalResponseString = '<numericalresponse answer="' + answerData.answer + '">\n';
if (answerData.default) {
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
numericalResponseString += ' <responseparam type="tolerance" default="' +
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
answerData.default + '" />\n';
}
}
......@@ -644,15 +644,15 @@
}
if (additionalTextHint.hint) {
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
additionalHintLine = '<correcthint' +
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
additionalTextHint.labelassign + '>' +
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
additionalTextHint.hint + '</correcthint>';
}
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
additionalAnswerString += ' <additional_answer answer="' + orMatch[1] + '">';
additionalAnswerString += additionalHintLine;
additionalAnswerString += '</additional_answer>\n';
......@@ -765,7 +765,7 @@
responseTypesSelector = responseTypes.join(', ');
// make temporary xml
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
$xml = $($.parseXML('<prob>' + xml + '</prob>'));
responseType = $xml.find(responseTypesSelector);
......@@ -783,7 +783,7 @@
}
if (beforeInputtype) {
// safe-lint: disable=javascript-jquery-insert-into-target
// xss-lint: disable=javascript-jquery-insert-into-target
responseType[0].insertBefore(child, inputtype);
} else {
responseType[0].appendChild(child);
......@@ -814,11 +814,11 @@
});
finalDemandHints = '';
if (demandHintTags.length) {
// safe-lint: disable=javascript-concat-html
// xss-lint: disable=javascript-concat-html
finalDemandHints = '\n<demandhint>\n' + demandHintTags.join('') + '</demandhint>';
}
// 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>';
return finalXml;
};
......
......@@ -747,7 +747,7 @@
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) {
......
......@@ -32,7 +32,7 @@ from django.utils.http import urlquote_plus
<script>
## 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.
## 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)}
</script>
</%block>
......
......@@ -64,27 +64,27 @@ $(function () {
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.
## safe-lint: disable=javascript-jquery-append
## xss-lint: disable=javascript-jquery-append
categoryData['data'].append( [tickIndex, section['percent']] )
## 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
## 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)] )
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'] )
else:
detail_tooltips[ section['category'] ] = [ section['detail'], ]
if 'mark' in section:
## safe-lint: disable=javascript-jquery-append
## xss-lint: disable=javascript-jquery-append
droppedScores.append( [tickIndex, 0.05] )
## safe-lint: disable=javascript-jquery-append
## xss-lint: disable=javascript-jquery-append
dropped_score_tooltips.append( section['mark']['detail'] )
tickIndex += 1
......@@ -107,7 +107,7 @@ $(function () {
else:
color = colors[ extraColorIndex % len(colors) ]
extraColorIndex += 1
## safe-lint: disable=javascript-jquery-append
## xss-lint: disable=javascript-jquery-append
series.append({
'label' : section['category'] + "-grade_breakdown",
'data' : [ [overviewBarX, section['percent']] ],
......@@ -131,7 +131,7 @@ $(function () {
descending_grades = sorted(grade_cutoffs, key=lambda x: grade_cutoffs[x], reverse=True)
for grade in descending_grades:
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) ] )
else:
grade_cutoff_ticks = [ ]
......@@ -284,7 +284,7 @@ $(function () {
edx.HtmlUtils.append(
$grade_detail_graph,
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('<span class=sr>'),
gettext('Overall Score'),
......
......@@ -20,7 +20,7 @@
<option value="flagged">${_("Flagged")}</option>
%endif
</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">
## Translators: This labels a group menu in forum navigation
<span class="sr">${_("Group:")}</span>
......@@ -31,7 +31,7 @@
<option value="${group['id']}">${group['name']}</option>
%endfor
</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">
## Translators: This labels a sort menu in forum navigation
<span class="sr">${_("Sort:")}</span>
......
......@@ -59,7 +59,7 @@
});
return item.render().el;
}, this);
// safe-lint: disable=javascript-jquery-append
// xss-lint: disable=javascript-jquery-append
this.$el.find('ol').append(items);
},
......
......@@ -63,7 +63,7 @@ class TestPaverQualityViolations(unittest.TestCase):
class TestPaverReportViolationsCounts(unittest.TestCase):
"""
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):
......@@ -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
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("""
test.html: 30:53: javascript-jquery-append: $('#test').append(print_tos);
......@@ -150,7 +150,7 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
""")
with open(self.f.name, 'w') as f:
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, {
'rules': {
'javascript-concat-html': 310,
......@@ -159,9 +159,9 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
'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 = textwrap.dedent("""
......@@ -169,15 +169,15 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
""")
with open(self.f.name, 'w') as f:
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, {
'rules': {},
'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("""
Linting lms/templates/navigation.html:
......@@ -190,26 +190,26 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
""")
with open(self.f.name, 'w') as f:
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)
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("""
Linting lms/templates/navigation.html:
""")
with open(self.f.name, 'w') as f:
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)
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.
"""
report = textwrap.dedent("""
......@@ -217,7 +217,7 @@ class TestPaverReportViolationsCounts(unittest.TestCase):
""")
with open(self.f.name, 'w') as f:
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)
......
"""
Tests for paver safecommit quality tasks
Tests for paver xsscommitlint quality tasks
"""
from mock import patch
from paver.easy import call_task
......@@ -9,36 +9,36 @@ import pavelib.quality
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.
"""
def setUp(self):
super(PaverSafeCommitTest, self).setUp()
super(PaverXSSCommitLintTest, self).setUp()
self.reset_task_messages()
@patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safecommit_count')
def test_safecommit_violation_number_not_found(self, _mock_count, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsscommitlint_count')
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.
"""
_mock_count.return_value = None
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, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safecommit_count')
def test_safecommit_vanilla(self, _mock_count, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsscommitlint_count')
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
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 paver.easy import call_task
......@@ -9,110 +9,110 @@ import pavelib.quality
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):
super(PaverSafeLintTest, self).setUp()
super(PaverXSSLintTest, self).setUp()
self.reset_task_messages()
@patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts')
def test_safelint_violation_number_not_found(self, _mock_counts, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsslint_counts')
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 = {}
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, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts')
def test_safelint_vanilla(self, _mock_counts, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsslint_counts')
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}
call_task('pavelib.quality.run_safelint')
call_task('pavelib.quality.run_xsslint')
@patch.object(pavelib.quality, '_write_metric')
@patch.object(pavelib.quality, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts')
def test_safelint_invalid_thresholds_option(self, _mock_counts, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsslint_counts')
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}
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, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts')
def test_safelint_invalid_thresholds_option_key(self, _mock_counts, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsslint_counts')
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}
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, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts')
def test_safelint_too_many_violations(self, _mock_counts, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsslint_counts')
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}
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, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts')
def test_safelint_under_limit(self, _mock_counts, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsslint_counts')
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}
# 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, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts')
def test_safelint_rule_violation_number_not_found(self, _mock_counts, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsslint_counts')
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.
"""
_mock_counts.return_value = {'total': 4}
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, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts')
def test_safelint_too_many_rule_violations(self, _mock_counts, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsslint_counts')
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}}
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, '_prepare_report_dir')
@patch.object(pavelib.quality, '_get_safelint_counts')
def test_safelint_under_rule_limit(self, _mock_counts, _mock_report_dir, _mock_write_metric):
@patch.object(pavelib.quality, '_get_xsslint_counts')
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}}
# 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):
("thresholds=", "t", "json containing limit for number of acceptable violations per rule"),
])
@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', '{}')
......@@ -342,42 +342,42 @@ def run_safelint(options):
)
)
safelint_script = "safe_template_linter.py"
safelint_report_dir = (Env.REPORT_DIR / "safelint")
safelint_report = safelint_report_dir / "safelint.report"
_prepare_report_dir(safelint_report_dir)
xsslint_script = "xss_linter.py"
xsslint_report_dir = (Env.REPORT_DIR / "xsslint")
xsslint_report = xsslint_report_dir / "xsslint.report"
_prepare_report_dir(xsslint_report_dir)
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,
safelint_script=safelint_script,
safelint_report=safelint_report,
xsslint_script=xsslint_script,
xsslint_report=xsslint_report,
),
ignore_error=True
)
safelint_counts = _get_safelint_counts(safelint_report)
xsslint_counts = _get_xsslint_counts(xsslint_report)
try:
metrics_str = "Number of {safelint_script} violations: {num_violations}\n".format(
safelint_script=safelint_script, num_violations=int(safelint_counts['total'])
metrics_str = "Number of {xsslint_script} violations: {num_violations}\n".format(
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"
rule_keys = sorted(safelint_counts['rules'].keys())
rule_keys = sorted(xsslint_counts['rules'].keys())
for rule in rule_keys:
metrics_str += "{rule} violations: {count}\n".format(
rule=rule,
count=int(safelint_counts['rules'][rule])
count=int(xsslint_counts['rules'][rule])
)
except TypeError:
raise BuildFailure(
"Error. Number of {safelint_script} violations could not be found in {safelint_report}".format(
safelint_script=safelint_script, safelint_report=safelint_report
"Error. Number of {xsslint_script} violations could not be found in {xsslint_report}".format(
xsslint_script=xsslint_script, xsslint_report=xsslint_report
)
)
metrics_report = (Env.METRICS_DIR / "safelint")
metrics_report = (Env.METRICS_DIR / "xsslint")
# Record the metric
_write_metric(metrics_str, metrics_report)
# Print number of violations to log.
......@@ -387,35 +387,35 @@ def run_safelint(options):
# Test total violations against threshold.
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(
count=safelint_counts['total'], violations_limit=violation_thresholds['total']
count=xsslint_counts['total'], violations_limit=violation_thresholds['total']
)
# Test rule violations against thresholds.
if 'rules' in violation_thresholds:
threshold_keys = sorted(violation_thresholds['rules'].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 += (
"\nNumber of {safelint_script} violations for {rule} could not be found in "
"{safelint_report}."
"\nNumber of {xsslint_script} violations for {rule} could not be found in "
"{xsslint_report}."
).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 += \
"\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],
)
if error_message is not "":
raise BuildFailure(
"SafeTemplateLinter Failed.\n{error_message}\n"
"See {safelint_report} or run the following command to hone in on the problem:\n"
" ./scripts/safe-commit-linter.sh -h".format(
error_message=error_message, safelint_report=safelint_report
"XSSLinter Failed.\n{error_message}\n"
"See {xsslint_report} or run the following command to hone in on the problem:\n"
" ./scripts/xss-commit-linter.sh -h".format(
error_message=error_message, xsslint_report=xsslint_report
)
)
......@@ -423,42 +423,42 @@ def run_safelint(options):
@task
@needs('pavelib.prereqs.install_python_prereqs')
@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"
safecommit_report_dir = (Env.REPORT_DIR / "safecommit")
safecommit_report = safecommit_report_dir / "safecommit.report"
_prepare_report_dir(safecommit_report_dir)
xsscommitlint_script = "xss-commit-linter.sh"
xsscommitlint_report_dir = (Env.REPORT_DIR / "xsscommitlint")
xsscommitlint_report = xsscommitlint_report_dir / "xsscommitlint.report"
_prepare_report_dir(xsscommitlint_report_dir)
sh(
"{repo_root}/scripts/{safecommit_script} | tee {safecommit_report}".format(
"{repo_root}/scripts/{xsscommitlint_script} | tee {xsscommitlint_report}".format(
repo_root=Env.REPO_ROOT,
safecommit_script=safecommit_script,
safecommit_report=safecommit_report,
xsscommitlint_script=xsscommitlint_script,
xsscommitlint_report=xsscommitlint_report,
),
ignore_error=True
)
safecommit_count = _get_safecommit_count(safecommit_report)
xsscommitlint_count = _get_xsscommitlint_count(xsscommitlint_report)
try:
num_violations = int(safecommit_count)
num_violations = int(xsscommitlint_count)
except TypeError:
raise BuildFailure(
"Error. Number of {safecommit_script} violations could not be found in {safecommit_report}".format(
safecommit_script=safecommit_script, safecommit_report=safecommit_report
"Error. Number of {xsscommitlint_script} violations could not be found in {xsscommitlint_report}".format(
xsscommitlint_script=xsscommitlint_script, xsscommitlint_report=xsscommitlint_report
)
)
# Print number of violations to log.
violations_count_str = "Number of {safecommit_script} violations: {num_violations}\n".format(
safecommit_script=safecommit_script, num_violations=num_violations
violations_count_str = "Number of {xsscommitlint_script} violations: {num_violations}\n".format(
xsscommitlint_script=xsscommitlint_script, num_violations=num_violations
)
# Record the metric
metrics_report = (Env.METRICS_DIR / "safecommit")
metrics_report = (Env.METRICS_DIR / "xsscommitlint")
_write_metric(violations_count_str, metrics_report)
# Output report to console.
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):
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:
filename: The name of the safelint report.
filename: The name of the xsslint report.
Returns:
A dict containing the following:
......@@ -566,15 +566,15 @@ def _get_safelint_counts(filename):
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:
filename: The name of the safecommit report.
filename: The name of the xsscommitlint report.
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)
......
......@@ -14,8 +14,8 @@ set -e
export PYLINT_THRESHOLD=3600
export ESLINT_THRESHOLD=10122
SAFELINT_THRESHOLDS=`cat scripts/safelint_thresholds.json`
export SAFELINT_THRESHOLDS=${SAFELINT_THRESHOLDS//[[:space:]]/}
XSSLINT_THRESHOLDS=`cat scripts/xsslint_thresholds.json`
export XSSLINT_THRESHOLDS=${XSSLINT_THRESHOLDS//[[:space:]]/}
doCheckVars() {
if [ -n "$CIRCLECI" ] ; then
......
......@@ -84,10 +84,10 @@ case "$TEST_SUITE" in
paver run_eslint -l $ESLINT_THRESHOLD > eslint.log || { cat eslint.log; EXIT=1; }
echo "Running code complexity report (python)."
paver run_complexity || echo "Unable to calculate code complexity. Ignoring error."
echo "Running safe template linter report."
paver run_safelint -t $SAFELINT_THRESHOLDS > safelint.log || { cat safelint.log; EXIT=1; }
echo "Running safe commit linter report."
paver run_safecommit_report > safecommit.log || { cat safecommit.log; EXIT=1; }
echo "Running xss linter report."
paver run_xsslint -t $XSSLINT_THRESHOLDS > xsslint.log || { cat xsslint.log; EXIT=1; }
echo "Running xss commit linter report."
paver run_xsscommitlint > xsscommitlint.log || { cat xsscommitlint.log; EXIT=1; }
# Run quality task. Pass in the 'fail-under' percentage to diff-quality
echo "Running diff quality."
paver run_quality -p 100 || EXIT=1
......
# -*- coding: utf-8 -*-
"""
Tests for safe_template_linter.py
Tests for xss_linter.py
"""
import re
import textwrap
......@@ -10,7 +10,7 @@ from unittest import TestCase
import mock
from ddt import data, ddt
from scripts.safe_template_linter import (
from scripts.xss_linter import (
FileResults,
JavaScriptLinter,
MakoTemplateLinter,
......@@ -93,7 +93,7 @@ class TestLinter(TestCase):
self.assertEqual(violation.rule, rule)
class TestSafeTemplateLinter(TestCase):
class TestXSSLinter(TestCase):
"""
Test some top-level linter functions
"""
......@@ -107,7 +107,7 @@ class TestSafeTemplateLinter(TestCase):
self.patch_is_valid_directory(UnderscoreTemplateLinter)
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()
self.addCleanup(patcher.stop)
......@@ -548,7 +548,7 @@ class TestMakoTemplateLinter(TestLinter):
# This is anything but a Mako 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)
......@@ -566,7 +566,7 @@ class TestMakoTemplateLinter(TestLinter):
mako_template = textwrap.dedent("""
<%page expression_filter="h"/>
## safe-lint: disable=mako-unwanted-html-filter
## xss-lint: disable=mako-unwanted-html-filter
${x | h}
""")
......@@ -982,25 +982,25 @@ class TestUnderscoreTemplateLinter(TestLinter):
@data(
{
'template':
'<% // safe-lint: disable=underscore-not-escaped %>\n'
'<% // xss-lint: disable=underscore-not-escaped %>\n'
'<%= message %>',
'is_disabled': [True],
},
{
'template':
'<% // safe-lint: disable=another-rule,underscore-not-escaped %>\n'
'<% // xss-lint: disable=another-rule,underscore-not-escaped %>\n'
'<%= message %>',
'is_disabled': [True],
},
{
'template':
'<% // safe-lint: disable=another-rule %>\n'
'<% // xss-lint: disable=another-rule %>\n'
'<%= message %>',
'is_disabled': [False],
},
{
'template':
'<% // safe-lint: disable=underscore-not-escaped %>\n'
'<% // xss-lint: disable=underscore-not-escaped %>\n'
'<%= message %>\n'
'<%= message %>',
'is_disabled': [True, False],
......@@ -1010,22 +1010,22 @@ class TestUnderscoreTemplateLinter(TestLinter):
'// This test does not use proper Underscore.js Template syntax\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'
' 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'
' 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 %>',
'is_disabled': [True, False],
},
{
'template':
'<%= message %><% // safe-lint: disable=underscore-not-escaped %>\n'
'<%= message %><% // xss-lint: disable=underscore-not-escaped %>\n'
'<%= message %>',
'is_disabled': [True, False],
},
{
'template':
'<%= message %>\n'
'<% // safe-lint: disable=underscore-not-escaped %>',
'<% // xss-lint: disable=underscore-not-escaped %>',
'is_disabled': [False],
},
)
......@@ -1052,7 +1052,7 @@ class TestUnderscoreTemplateLinter(TestLinter):
results = FileResults('')
template = textwrap.dedent("""
<% // safe-lint: disable=underscore-not-escaped %>
<% // xss-lint: disable=underscore-not-escaped %>
<%= message %>
<%= message %>
""")
......
......@@ -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
# commit.
# Executes xss_linter.py on the set of files in a particular git commit.
#
###############################################################################
show_help() {
echo "Usage: safe-commit-linter.sh [OPTION]"
echo "Runs the Safe Template Linter against all files in a git commit."
echo "Usage: xss-commit-linter.sh [OPTION]"
echo "Runs the XSS Linter against all files in a git commit."
echo ""
echo "Mandatory arguments to long options are mandatory for short options too."
echo " -h, --help Output this help."
......@@ -24,10 +23,10 @@ show_help() {
echo "This scripts does not give a grand total. Be sure to check for"
echo "0 violations on each file."
echo ""
echo "For more help using the safe template linter, including details on how"
echo "to understand and fix any violations, read the docs here:"
echo "For more help using the xss linter, including details on how to"
echo "understand and fix any violations, read the docs here:"
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
for f in $diff_files; do
echo ""
echo "Linting $f:"
./scripts/safe_template_linter.py $f
./scripts/xss_linter.py $f
done
fi
#!/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
......@@ -192,7 +192,7 @@ class Rules(Enum):
An Enum of each rule which the linter will check.
"""
# 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_multiple_page_tags = 'mako-multiple-page-tags'
mako_unparseable_expression = 'mako-unparseable-expression'
......@@ -300,7 +300,7 @@ class RuleViolation(object):
Pragma format::
safe-lint: disable=violation-name,other-violation-name
xss-lint: disable=violation-name,other-violation-name
Arguments:
string: The string of code in which to search for the pragma.
......@@ -314,7 +314,7 @@ class RuleViolation(object):
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:
return
if scope_start_string:
......@@ -398,14 +398,14 @@ class ExpressionRuleViolation(RuleViolation):
Pragma format::
safe-lint: disable=violation-name,other-violation-name
xss-lint: disable=violation-name,other-violation-name
Examples::
<% // safe-lint: disable=underscore-not-escaped %>
<% // xss-lint: disable=underscore-not-escaped %>
<%= gettext('Single Line') %>
<%= gettext('Single Line') %><% // safe-lint: disable=underscore-not-escaped %>
<%= gettext('Single Line') %><% // xss-lint: disable=underscore-not-escaped %>
Arguments:
string_lines: A StringLines containing the contents of the file in
......@@ -1421,7 +1421,7 @@ class JavaScriptLinter(BaseLinter):
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.
"""
......@@ -1787,7 +1787,7 @@ class PythonLinter(BaseLinter):
if file_name.lower().endswith('tests.py'):
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__):
return results
......@@ -2493,6 +2493,7 @@ SKIP_DIRS = (
'.git',
'.pycharm_helpers',
'common/static/xmodule/modules',
'common/static/bundles',
'perf_tests',
'node_modules',
'reports/diff_quality',
......@@ -2615,11 +2616,11 @@ def main():
Prints all violations.
"""
epilog = "For more help using the safe template linter, including details on how\n"
epilog += "to understand and fix any violations, read the docs here:\n"
epilog = "For more help using the xss linter, including details on how to\n"
epilog += "understand and fix any violations, read the docs here:\n"
epilog += "\n"
# 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(
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