yaml.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # Copyright (c) 2017 VMware, Inc.
  2. #
  3. # SPDX-License-Identifier: Apache-2.0
  4. r"""
  5. ==============
  6. YAML Formatter
  7. ==============
  8. This formatter outputs the issues in a yaml format.
  9. :Example:
  10. .. code-block:: none
  11. errors: []
  12. generated_at: '2017-03-09T22:29:30Z'
  13. metrics:
  14. _totals:
  15. CONFIDENCE.HIGH: 1
  16. CONFIDENCE.LOW: 0
  17. CONFIDENCE.MEDIUM: 0
  18. CONFIDENCE.UNDEFINED: 0
  19. SEVERITY.HIGH: 0
  20. SEVERITY.LOW: 0
  21. SEVERITY.MEDIUM: 1
  22. SEVERITY.UNDEFINED: 0
  23. loc: 9
  24. nosec: 0
  25. examples/yaml_load.py:
  26. CONFIDENCE.HIGH: 1
  27. CONFIDENCE.LOW: 0
  28. CONFIDENCE.MEDIUM: 0
  29. CONFIDENCE.UNDEFINED: 0
  30. SEVERITY.HIGH: 0
  31. SEVERITY.LOW: 0
  32. SEVERITY.MEDIUM: 1
  33. SEVERITY.UNDEFINED: 0
  34. loc: 9
  35. nosec: 0
  36. results:
  37. - code: '5 ystr = yaml.dump({''a'' : 1, ''b'' : 2, ''c'' : 3})\n
  38. 6 y = yaml.load(ystr)\n7 yaml.dump(y)\n'
  39. filename: examples/yaml_load.py
  40. issue_confidence: HIGH
  41. issue_severity: MEDIUM
  42. issue_text: Use of unsafe yaml load. Allows instantiation of arbitrary
  43. objects.
  44. Consider yaml.safe_load().
  45. line_number: 6
  46. line_range:
  47. - 6
  48. more_info: https://bandit.readthedocs.io/en/latest/
  49. test_id: B506
  50. test_name: yaml_load
  51. .. versionadded:: 1.5.0
  52. .. versionchanged:: 1.7.3
  53. New field `CWE` added to output
  54. """
  55. # Necessary for this formatter to work when imported on Python 2. Importing
  56. # the standard library's yaml module conflicts with the name of this module.
  57. import datetime
  58. import logging
  59. import operator
  60. import sys
  61. import yaml
  62. from bandit.core import docs_utils
  63. LOG = logging.getLogger(__name__)
  64. def report(manager, fileobj, sev_level, conf_level, lines=-1):
  65. """Prints issues in YAML format
  66. :param manager: the bandit manager object
  67. :param fileobj: The output file object, which may be sys.stdout
  68. :param sev_level: Filtering severity level
  69. :param conf_level: Filtering confidence level
  70. :param lines: Number of lines to report, -1 for all
  71. """
  72. machine_output = {"results": [], "errors": []}
  73. for (fname, reason) in manager.get_skipped():
  74. machine_output["errors"].append({"filename": fname, "reason": reason})
  75. results = manager.get_issue_list(
  76. sev_level=sev_level, conf_level=conf_level
  77. )
  78. collector = [r.as_dict(max_lines=lines) for r in results]
  79. for elem in collector:
  80. elem["more_info"] = docs_utils.get_url(elem["test_id"])
  81. itemgetter = operator.itemgetter
  82. if manager.agg_type == "vuln":
  83. machine_output["results"] = sorted(
  84. collector, key=itemgetter("test_name")
  85. )
  86. else:
  87. machine_output["results"] = sorted(
  88. collector, key=itemgetter("filename")
  89. )
  90. machine_output["metrics"] = manager.metrics.data
  91. for result in machine_output["results"]:
  92. if "code" in result:
  93. code = result["code"].replace("\n", "\\n")
  94. result["code"] = code
  95. # timezone agnostic format
  96. TS_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
  97. time_string = datetime.datetime.utcnow().strftime(TS_FORMAT)
  98. machine_output["generated_at"] = time_string
  99. yaml.safe_dump(machine_output, fileobj, default_flow_style=False)
  100. if fileobj.name != sys.stdout.name:
  101. LOG.info("YAML output written to file: %s", fileobj.name)