11import json
2+ import os
23from datetime import datetime
34from enum import Enum
45from pathlib import Path
89import requests
910from jsonschema import Draft7Validator
1011
12+ from cvelib import __version__
13+
1114SCHEMA_DIR = Path (__file__ ).parent / "schemas"
1215
1316
@@ -178,10 +181,33 @@ def _add_provider_metadata(self, cve_json: dict) -> dict:
178181 cve_json ["providerMetadata" ] = {"orgId" : org_id }
179182 return cve_json
180183
184+ @staticmethod
185+ def _add_generator (cve_json : dict ) -> dict :
186+ """Add the x_generator field to the CVE record if defined.
187+
188+ Determine and inject the value of the x_generator field into all created/updated CVE
189+ records to identify this library as the tool that was used to do so. Override this value
190+ via the CVE_GENERATOR env var; set this env var to the value of "-" to omit adding this
191+ field into the CVE record. Existing x_generator values are not overridden.
192+ """
193+ generator = os .getenv ("CVE_GENERATOR" )
194+
195+ # Skip adding the x_generator field if undesired or already present
196+ if generator == "-" or "x_generator" in cve_json :
197+ return cve_json
198+
199+ # If no custom value is specified, use cvelib
200+ if generator is None :
201+ generator = f"cvelib { __version__ } "
202+
203+ cve_json ["x_generator" ] = {"engine" : generator }
204+ return cve_json
205+
181206 def publish (self , cve_id : str , cve_json : dict , validate : bool = True ) -> dict :
182207 """Publish a CVE from a JSON object representing the CNA container data."""
183208 cve_json = self ._extract_cna_container (cve_json )
184209 cve_json = self ._add_provider_metadata (cve_json )
210+ cve_json = self ._add_generator (cve_json )
185211 if validate :
186212 CveRecord .validate (cve_json , CveRecord .Schemas .CNA_PUBLISHED )
187213
@@ -194,6 +220,7 @@ def update_published(self, cve_id: str, cve_json: dict, validate: bool = True) -
194220 """Update a published CVE record from a JSON object representing the CNA container data."""
195221 cve_json = self ._extract_cna_container (cve_json )
196222 cve_json = self ._add_provider_metadata (cve_json )
223+ cve_json = self ._add_generator (cve_json )
197224 if validate :
198225 CveRecord .validate (cve_json , CveRecord .Schemas .CNA_PUBLISHED )
199226
@@ -206,6 +233,7 @@ def publish_adp(self, cve_id: str, cve_json: dict, validate: bool = True) -> dic
206233 """Add or update an ADP container from a JSON object representing the ADP container data."""
207234 cve_json = self ._extract_adp_container (cve_json )
208235 cve_json = self ._add_provider_metadata (cve_json )
236+ cve_json = self ._add_generator (cve_json )
209237 if validate :
210238 CveRecord .validate (cve_json , CveRecord .Schemas .ADP )
211239
@@ -218,6 +246,7 @@ def reject(self, cve_id: str, cve_json: dict, validate: bool = True) -> dict:
218246 """Reject a CVE from a JSON object representing the CNA container data."""
219247 cve_json = self ._extract_cna_container (cve_json )
220248 cve_json = self ._add_provider_metadata (cve_json )
249+ cve_json = self ._add_generator (cve_json )
221250 if validate :
222251 CveRecord .validate (cve_json , CveRecord .Schemas .CNA_REJECTED )
223252
@@ -230,6 +259,7 @@ def update_rejected(self, cve_id: str, cve_json: dict, validate: bool = True) ->
230259 """Update a rejected CVE record from a JSON object representing the CNA container data."""
231260 cve_json = self ._extract_cna_container (cve_json )
232261 cve_json = self ._add_provider_metadata (cve_json )
262+ cve_json = self ._add_generator (cve_json )
233263 if validate :
234264 CveRecord .validate (cve_json , CveRecord .Schemas .CNA_REJECTED )
235265
0 commit comments