diff --git a/tools/jsonCveGenerator.py b/tools/jsonCveGenerator.py new file mode 100755 index 00000000000..0aeb5b5ca87 --- /dev/null +++ b/tools/jsonCveGenerator.py @@ -0,0 +1,107 @@ +#! /usr/bin/python3 + +from __future__ import absolute_import, division, print_function +import json + +class References: + def __init__( self, references ): + assert type( references ) == type( list() ), "references is a list" + assert len( references ) > 0, "references cannot be empty" + assert len( references ) <= 500, "too many referenes" + for elem in references: + assert type( elem ) == type( str() ), "Every elem in references must be a string" + self.references = references + + def cveMap( self ): + cveObj = { "reference_data": [], } + for elem in self.references: + cveObj[ "reference_data" ].append( { "url": elem, } ) + return cveObj + +class ProblemDescription: + def __init__( self, description ): + assert description != "", "description must be set" + self.description = description + + def cveMap( self ): + cveObj = { "description_data": [ + { "lang": "eng", "value": self.description, } + ], } + return cveObj + +class ProblemSummary: + def __init__( self, summary ): + assert summary != "", "Summary must be set" + self.summary = summary + + def cveMap( self ): + cveObj = { "problemtype_data": [ + { "description": [ + { "lang": "eng", "value": self.summary, } + ], } ], } + return cveObj + +class AffectedProduct: + def __init__( self, vendor, productName, affectedVersions ): + assert vendor != "", "Vendor must be set" + self.vendor = vendor + assert productName != "", "productName must be set" + self.productName = productName + assert type( affectedVersions ) == type( list() ), "affectedVersions is a list of versions" + assert len( affectedVersions ) > 0, "affectedVersions cannot be empty" + for elem in affectedVersions: + assert type( elem ) == type( str() ), "Every elem in affectedVersions must be a string" + self.affectedVersions = affectedVersions + + def cveMap( self ): + outputMap = { + "vendor_name": self.vendor, + "product": { "product_data": [ { "product_name": self.productName, + "version": { "version_data": [], } + }, + ], }, + } + for elem in self.affectedVersions: + outputMap[ "product" ][ "product_data" ][ 0 ][ + "version" ][ "version_data" ].append( { "version_value": elem } ) + return outputMap + +class CveMeta: + def __init__( self, assigner, cveId ): + self.assigner = assigner + assert cveId != "", "CVE-ID must be set" + self.cveId = cveId + + def cveMap( self ): + outputMap = {} + if self.assigner: + outputMap[ "ASSIGNER" ] = self.assigner + outputMap[ "ID" ] = self.cveId + return outputMap + +def generateCve( cveMeta, affectedProduct, summary, references, description ): + # TODO: While the spec currently allows for lists of items such as affected products, + # summaries, and descriptions, this tool does not presently support those + cveObj = { "data_type": "CVE", + "data_format": "MITRE", + "data_version": "4.0", + } + cveObj[ "CVE_data_meta" ] = cveMeta.cveMap() + cveObj[ "affects" ] = { "vendor": { "vendor_data": [ affectedProduct.cveMap() ] } } + cveObj[ "problemtype" ] = summary.cveMap() + cveObj[ "references" ] = references.cveMap() + cveObj[ "description" ] = description.cveMap() + return cveObj + +if __name__ == "__main__": + print ( "Sample output ----" ) + cveMeta = CveMeta( assigner="psirt@us.ibm.com", cveId="CVE-2017-1194" ) + affectedProd = AffectedProduct( vendor="IBM", + productName="WebSphere Application Server", + affectedVersions=[ "7.0, 8.0, 8.5, 9.0" ] ) + summary = ProblemSummary( summary="Cross-site request forgery" ) + refs = References( references=[ "http://www.ibm.com/support/docview.wss?uid=swg22001226", ] ) + description = ProblemDescription( description="IBM WebSphere Application Server 7.0, 8.0, 8.5, and 9.0 is vulnerable to cross-site request forgery which could allow an attacker to execute malicious and unauthorized actions transmitted from a user that the website trusts. IBM X-Force ID: 123669." ) + jsonObj = generateCve( cveMeta, affectedProd, summary, refs, description ) + jsonPretty = json.dumps( jsonObj, indent=4, sort_keys=True ) + print( jsonPretty )