# Copyright (c) 2015 Rackspace, Inc. # Copyright (c) 2015 Hewlett Packard Enterprise # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. r""" ============== HTML formatter ============== This formatter outputs the issues as HTML. :Example: .. code-block:: html Bandit Report
Metrics:
Total lines of code: 9
Total lines skipped (#nosec): 0

yaml_load: Use of unsafe yaml load. Allows instantiation of arbitrary objects. Consider yaml.safe_load().
Test ID: B506
Severity: MEDIUM
Confidence: HIGH
File: examples/yaml_load.py
More info: https://bandit.readthedocs.io/en/latest/plugins/yaml_load.html
    5       ystr = yaml.dump({'a' : 1, 'b' : 2, 'c' : 3})
    6       y = yaml.load(ystr)
    7       yaml.dump(y)
    
.. versionadded:: 0.14.0 """ from __future__ import absolute_import import logging import sys import six from bandit.core import docs_utils from bandit.core import test_properties from bandit.formatters import utils if not six.PY2: from html import escape as html_escape else: from cgi import escape as html_escape LOG = logging.getLogger(__name__) @test_properties.accepts_baseline def report(manager, fileobj, sev_level, conf_level, lines=-1): """Writes issues to 'fileobj' in HTML format :param manager: the bandit manager object :param fileobj: The output file object, which may be sys.stdout :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all """ header_block = u""" Bandit Report """ report_block = u""" {metrics} {skipped}
{results}
""" issue_block = u"""
{test_name}: {test_text}
Test ID: {test_id}
Severity: {severity}
Confidence: {confidence}
File: {path}
More info: {url}
{code} {candidates}
""" code_block = u"""
{code}
""" candidate_block = u"""

Candidates: {candidate_list}
""" candidate_issue = u"""
{code}
""" skipped_block = u"""
Skipped files:

{files_list}
""" metrics_block = u"""
Metrics:
Total lines of code: {loc}
Total lines skipped (#nosec): {nosec}
""" issues = manager.get_issue_list(sev_level=sev_level, conf_level=conf_level) baseline = not isinstance(issues, list) # build the skipped string to insert in the report skipped_str = ''.join('%s reason: %s
' % (fname, reason) for fname, reason in manager.get_skipped()) if skipped_str: skipped_text = skipped_block.format(files_list=skipped_str) else: skipped_text = '' # build the results string to insert in the report results_str = '' for index, issue in enumerate(issues): if not baseline or len(issues[issue]) == 1: candidates = '' safe_code = html_escape(issue.get_code(lines, True). strip('\n').lstrip(' ')) code = code_block.format(code=safe_code) else: candidates_str = '' code = '' for candidate in issues[issue]: candidate_code = html_escape(candidate.get_code(lines, True). strip('\n').lstrip(' ')) candidates_str += candidate_issue.format(code=candidate_code) candidates = candidate_block.format(candidate_list=candidates_str) url = docs_utils.get_url(issue.test_id) results_str += issue_block.format(issue_no=index, issue_class='issue-sev-{}'. format(issue.severity.lower()), test_name=issue.test, test_id=issue.test_id, test_text=issue.text, severity=issue.severity, confidence=issue.confidence, path=issue.fname, code=code, candidates=candidates, url=url) # build the metrics string to insert in the report metrics_summary = metrics_block.format( loc=manager.metrics.data['_totals']['loc'], nosec=manager.metrics.data['_totals']['nosec']) # build the report and output it report_contents = report_block.format(metrics=metrics_summary, skipped=skipped_text, results=results_str) with fileobj: wrapped_file = utils.wrap_file_object(fileobj) wrapped_file.write(utils.convert_file_contents(header_block)) wrapped_file.write(utils.convert_file_contents(report_contents)) if fileobj.name != sys.stdout.name: LOG.info("HTML output written to file: %s", fileobj.name)