CVEAggregate Save

Build a CVE library with aggregated CISA, EPSS and CVSS data

Project README

CVEAggregate

Build a CVE library with aggregated CISA, EPSS and CVSS data

  • CISA Values : The remediation due date (or null)
  • EPSS Values : The EPSS probability score (or 0)
  • CVSS Values : V2 and/or V3 vector strings (or null)
/** CommonJS 
 * When requiring, reference the .cjs files in the /lib folder
*/
const { CVEAggregate } = require("/path/to/CVEAggregate/lib/index.cjs")

/** ESM 
 * When importing, reference the .js files in the /src folder
*/
import { CVEAggregate } from "/path/to/CVEAggregate/src/index.js"

// or

const { CVEAggregate } = await import("/path/to/CVEAggregate/src/index.js")
/* If verbose, will log stuff to console */
const verbose = true
const cves = new CVEAggregate('/path/to/cves.json', verbose)

Building the aggregate

# Quick-build/update full list (with all CVEs)
$ node /path/to/CVEAggregate/build.js /path/to/cves.json

# Quick-build/update short list (ignoring inactive CVEs)
$ node /path/to/CVEAggregate/update.js /path/to/cves.json

The path provided to the constructor will load file if exists and will save updates to same location.

The build process will collect all existing CVE Ids regardless of their state or age.

The update process will collect only the CVE Ids that have associated aggregate data (epps, cvss, cisa).

Note: Once the initial aggregate has been created, subsequent build or update calls will only collect new items since last save.

const saveAtEachStage = true

/* Build/update full list */
await cves.build(saveAtEachStage)

/* Build/update short list */
await cves.update(saveAtEachStage)

/* List new items since last load, plus aggregate totals and details */
cves.report() 

/* Return the full json aggregate */
const data = cves.dump()     

/* Save the current cache (to the filepath provided) */
cves.save()

/* Load the cache from file (from the filepath provided) */
cves.load()

/* Force rebuild full list */
await cves.forceBuild(saveAtEachStage)

/* Force rebuild short list */
await cves.forceUpdate(saveAtEachStage)

Accessing the aggregate

Helper functions are provided to help access and reference the aggregate

const listOfCves = ['CVE-2023-35390','CVE-2023-35391','CVE-2023-38180']

/* Get matching cve entries as an object */
const map = cves.map(...listOfCves)
//> {
//>   'CVE-2023-35390': {
//>     days: 0,
//>     cisa: null,
//>     epss: 0.00564,
//>     cvss2: null,
//>     cvss3: 'CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H'
//>   },
//>   'CVE-2023-35391': {
//>     days: 0,
//>     cisa: null,
//>     epss: 0.00114,
//>     cvss2: null,
//>     cvss3: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N'
//>   },
//>   'CVE-2023-38180': {
//>     days: 21,
//>     cisa: '2023-08-30',
//>     epss: 0.00484,
//>     cvss2: null,
//>     cvss3: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H'
//>   }
//> }

/* Get matching cve entries as an array */
const list = cves.list(...listOfCves)
//> [
//>   {
//>     id: 'CVE-2023-35390',
//>     days: 0,
//>     cisa: null,
//>     epss: 0.00564,
//>     cvss2: null,
//>     cvss3: 'CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H'
//>   },
//>   {
//>     id: 'CVE-2023-35391',
//>     days: 0,
//>     cisa: null,
//>     epss: 0.00114,
//>     cvss2: null,
//>     cvss3: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N'
//>   },
//>   {
//>     id: 'CVE-2023-38180',
//>     days: 21,
//>     cisa: '2023-08-30',
//>     epss: 0.00484,
//>     cvss2: null,
//>     cvss3: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H'
//>   }
//> ]

/* Get the whole list of CVE IDs in the cache */
const allCVEs = cves.cveList()

Get a value reduced/scaled across one or more CVE Ids

/* Check one or more CVE Ids if (any) in the CISA KEV */
const inKEV = cves.getCISA(...listOfCves)   
//> true

/* Get the scaled EPSS score for one or more CVE Ids */
const epssScore = cves.getEPSS(...listOfCves)    
//> 0.011580786319263958

/* Get the maximum CVSS score across one or more CVE Ids */
const cvssScore = cves.getCVSS(...listOfCves)
//> 7.8

Get the full mapping of CVE Ids -to- values

const cisaMap = cves.mapCISA(...listOfCves) 
//> { 
//>   'CVE-2023-35390': null, 
//>   'CVE-2023-35391': null, 
//>   'CVE-2023-38180': '2023-08-30' 
//> }

const epssMap = cves.mapEPSS(...listOfCves)
//> { 
//>   'CVE-2023-35390': 0.00564, 
//>   'CVE-2023-35391': 0.00114, 
//>   'CVE-2023-38180': 0.00484 
//> }

const cvssMap = cves.mapCVSS(...listOfCves)
//> {
//>   'CVE-2023-35390': 'CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H',
//>   'CVE-2023-35391': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N',
//>   'CVE-2023-38180': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H'
//> }

Search the aggregate with criteria (gt, gte, lt, lte, eq, ne)

const critical = cves.search({ 
    epss:{ gt:0.7 }, 
    cvss:{ gt:9.0 },
    cisa:{ gte:'2023-09-01' }
})
//> {
//>   'CVE-2023-24489': { daysUntilDue: -14, cisa: '2023-09-06', epss: 0.97441, cvss: 9.8 },
//>   'CVE-2023-38035': { daysUntilDue: -8, cisa: '2023-09-12', epss: 0.96013, cvss: 9.8 },
//>   'CVE-2023-33246': { daysUntilDue: 7, cisa: '2023-09-27', epss: 0.97146, cvss: 9.8 },
//>   'CVE-2021-3129': { daysUntilDue: 19, cisa: '2023-10-09', epss: 0.97515, cvss: 9.8 }
//> }

Calculations

The aggregate uses CVSS vectors and calculates the CVSS scores as needed

This allows the ability to manipulate vectors with optional temporal and environmental metrics

//Calculate a CVSSv2 vector details
const cvss2 = cves.calculateCVSS("AV:N/AC:L/Au:N/C:C/I:C/A:C")
//> {
//>   baseMetricScore: 7.2,
//>   baseSeverity: 'High',
//>   baseImpact: 10.00084536,
//>   baseExploitability: 4.1086848,
//>   temporalMetricScore: 7.2,
//>   temporalSeverity: 'High',
//>   environmentalMetricScore: 7.2,
//>   environmentalSeverity: 'High',
//>   environmentalModifiedImpact: 10,
//>   metricValues: { AV:'N', AC:'L', Au:'N', C:'C', I:'C', A:'C' },
//>   vectorString: 'AV:N/AC:L/Au:N/C:C/I:C/A:C/E:ND/RL:ND/RC:ND/CDP:ND/TD:ND/CR:ND/IR:ND/AR:ND',
//>   version: 'CVSS:2'
//> }

//Calculate a CVSSv3 vector details
const cvss3 = cves.calculateCVSS("CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H")
//> {
//>   baseMetricScore: 7.8,
//>   baseSeverity: 'High',
//>   baseImpact: 5.873118720000001,
//>   baseExploitability: 1.8345765900000002,
//>   temporalMetricScore: 7.8,
//>   temporalSeverity: 'High',
//>   environmentalMetricScore: 7.8,
//>   environmentalSeverity: 'High',
//>   environmentalModifiedImpact: 5.873118720000001,
//>   metricValues: { AV:'L', AC:'L', PR:'N', UI:'R', S:'U', C:'H', I:'H', A:'H' },
//>   vectorString: 'CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H/E:X/RL:X/RC:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MPR:X/MUI:X/MS:X/MC:X/MI:X/MA:X',
//>   version: 'CVSS:3.1'
//> }

Aggregate structure

Example of the aggregated cves.json

{
    "lastUpdated": "2023-08-31T14:41:33.076Z",
    "cvesUpdated": null,
    "cisaUpdated": "2023-08-31T14:35:31.532Z",
    "epssUpdated": "2023-08-31T14:41:33.076Z",
    "cvssUpdated": "2023-08-31T14:49:33.076Z",
    "lastCount": 216857,
    "cves": {
         "CVE-2018-4939": {
            "days": 181,
            "cisa": "2022-05-03",
            "epss": 0.97236,
            "cvss2": "AV:N/AC:L/Au:N/C:C/I:C/A:C",
            "cvss3": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
        },
        "CVE-2018-4878": {
            "days": 181,
            "cisa": "2022-05-03",
            "epss": 0.9742,
            "cvss2": "AV:N/AC:L/Au:N/C:P/I:P/A:P",
            "cvss3": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
        },
        ...
    }
}
Open Source Agenda is not affiliated with "CVEAggregate" Project. README Source: r3volved/CVEAggregate

Open Source Agenda Badge

Open Source Agenda Rating