# 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""" Description ----------- This formatter outputs the issues as HTML. Sample Output ------------- .. code-block:: html Bandit Report
Metrics:
Total lines of code: 5
Total lines skipped (#nosec): 0

blacklist_calls: Use of unsafe yaml load. Allows instantiation of arbitrary objects. Consider yaml.safe_load().
Severity: MEDIUM
Confidence: HIGH
File: examples/yaml_load.py
    4       ystr = yaml.dump({'a' : 1, 'b' : 2, 'c' : 3})
    5       y = yaml.load(ystr)
    6       yaml.dump(y)
    
.. versionadded:: 0.14.0 """ import logging from bandit.core.test_properties import accepts_baseline from bandit.core import utils logger = logging.getLogger(__name__) @accepts_baseline def report(manager, filename, sev_level, conf_level, lines=-1): """Writes issues to 'filename' in HTML format :param manager: the bandit manager object :param filename: output file name :param sev_level: Filtering severity level :param conf_level: Filtering confidence level :param lines: Number of lines to report, -1 for all """ header_block = """ Bandit Report """ report_block = """ {metrics} {skipped}
{results} """ issue_block = """
{test_name}: {test_text}
Severity: {severity}
Confidence: {confidence}
File: {path}
{code} {candidates}
""" code_block = """
{code}
""" candidate_block = """
Candidates: {candidate_list}
""" candidate_issue = """
{code}
""" skipped_block = """
Skipped files:

{files_list}
""" metrics_block = """
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 - %s\n' % (fname, reason) for fname, reason in manager.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 = '' code = code_block.format(code=issue.get_code(lines, True). strip('\n').lstrip(' ')) else: candidates_str = '' code = '' for candidate in issues[issue]: candidate_code = (candidate.get_code(lines, True).strip('\n'). lstrip(' ')) candidates_str += candidate_issue.format(code=candidate_code) candidates = candidate_block.format(candidate_list=candidates_str) results_str += issue_block.format(issue_no=index, issue_class='issue-sev-{}'. format(issue.severity.lower()), test_name=issue.test, test_text=issue.text, severity=issue.severity, confidence=issue.confidence, path=issue.fname, code=code, candidates=candidates) # 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 utils.output_file(filename, 'w') as fout: fout.write(header_block) fout.write(report_contents) if filename is not None: logger.info("HTML output written to file: %s" % filename)