cve-json-to-text.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #!/bin/env python3
  2. # SPDX-FileCopyrightText: OpenEmbedded Contributors
  3. #
  4. # SPDX-License-Identifier: MIT
  5. # CVE results conversion script: JSON format to text
  6. # Derived from cve-report.py from Oniro (MIT, by Huawei Inc)
  7. import sys
  8. import getopt
  9. infile = "in.json"
  10. outfile = "out.txt"
  11. def show_syntax_and_exit(code):
  12. """
  13. Show the program syntax and exit with an errror
  14. Arguments:
  15. code: the error code to return
  16. """
  17. print("Syntax: %s [-h] [-i inputJSONfile][-o outputfile]" % sys.argv[0])
  18. sys.exit(code)
  19. def exit_error(code, message):
  20. """
  21. Show the error message and exit with an errror
  22. Arguments:
  23. code: the error code to return
  24. message: the message to show
  25. """
  26. print("Error: %s" % message)
  27. sys.exit(code)
  28. def parse_args(argv):
  29. """
  30. Parse the program arguments, put options in global variables
  31. Arguments:
  32. argv: program arguments
  33. """
  34. global infile, outfile
  35. try:
  36. opts, args = getopt.getopt(
  37. argv, "hi:o:", ["help", "input", "output"]
  38. )
  39. except getopt.GetoptError:
  40. show_syntax_and_exit(1)
  41. for opt, arg in opts:
  42. if opt in ("-h", "--help"):
  43. show_syntax_and_exit(0)
  44. elif opt in ("-a", "--all"):
  45. show_all = True
  46. show_unknown = True
  47. elif opt in ("-i", "--input"):
  48. infile = arg
  49. def load_json(filename):
  50. """
  51. Load the JSON file, return the resulting dictionary
  52. Arguments:
  53. filename: the file to open
  54. Returns:
  55. Parsed file as a dictionary
  56. """
  57. import json
  58. out = {}
  59. try:
  60. with open(filename, "r") as f:
  61. out = json.load(f)
  62. except FileNotFoundError:
  63. exit_error(1, "Input file (%s) not found" % (filename))
  64. except json.decoder.JSONDecodeError as error:
  65. exit_error(1, "Malformed JSON file: %s" % str(error))
  66. return out
  67. def process_data(filename, data):
  68. """
  69. Write the resulting CSV with one line for each package
  70. Arguments:
  71. filename: the file to write to
  72. data: dictionary from parsing the JSON file
  73. Returns:
  74. None
  75. """
  76. if not "version" in data or data["version"] != "1":
  77. exit_error(1, "Unrecognized format version number")
  78. if not "package" in data:
  79. exit_error(1, "Mandatory 'package' key not found")
  80. lines = ""
  81. total_issue_count = 0
  82. for package in data["package"]:
  83. package_info = ""
  84. keys_in_package = {"name", "layer", "version", "issue"}
  85. if keys_in_package - package.keys():
  86. exit_error(
  87. 1,
  88. "Missing a mandatory key in package: %s"
  89. % (keys_in_package - package.keys()),
  90. )
  91. package_info += "LAYER: %s\n" % package["layer"]
  92. package_info += "PACKAGE NAME: %s\n" % package["name"]
  93. package_info += "PACKAGE VERSION: %s\n" % package["version"]
  94. for issue in package["issue"]:
  95. keys_in_issue = {"id", "status", "detail"}
  96. if keys_in_issue - issue.keys():
  97. print("Warning: Missing keys %s in 'issue' for the package '%s'"
  98. % (keys_in_issue - issue.keys(), package["name"]))
  99. lines += package_info
  100. lines += "CVE: %s\n" % issue["id"]
  101. lines += "CVE STATUS: %s\n" % issue["status"]
  102. lines += "CVE DETAIL: %s\n" % issue["detail"]
  103. if "description" in issue:
  104. lines += "CVE DESCRIPTION: %s\n" % issue["description"]
  105. if "summary" in issue:
  106. lines += "CVE SUMMARY: %s\n" % issue["summary"]
  107. if "scorev2" in issue:
  108. lines += "CVSS v2 BASE SCORE: %s\n" % issue["scorev2"]
  109. if "scorev3" in issue:
  110. lines += "CVSS v3 BASE SCORE: %s\n" % issue["scorev3"]
  111. if "scorev4" in issue:
  112. lines += "CVSS v4 BASE SCORE: %s\n" % issue["scorev4"]
  113. if "vector" in issue:
  114. lines += "VECTOR: %s\n" % issue["vector"]
  115. if "vectorString" in issue:
  116. lines += "VECTORSTRING: %s\n" % issue["vectorString"]
  117. lines += "MORE INFORMATION: https://nvd.nist.gov/vuln/detail/%s\n" % issue["id"]
  118. lines += "\n"
  119. with open(filename, "w") as f:
  120. f.write(lines)
  121. def main(argv):
  122. parse_args(argv)
  123. data = load_json(infile)
  124. process_data(outfile, data)
  125. if __name__ == "__main__":
  126. main(sys.argv[1:])