From f610b4908a7e83a9eac032f142720aef96ed9af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Helmke?= Date: Mon, 1 Jul 2024 10:44:12 +0200 Subject: [PATCH] update schema validation to v2.2.0, include cvss-v4.0 --- .github/workflows/validate_schema.yml | 2 +- .../schema/cve_item-v2.2.0.schema.json | 446 ++++++++++++++++++ _scripts/contrib/schema/cvss-v4.0.schema.json | 387 +++++++++++++++ _scripts/validate_schema-v2.2.0.bash | 47 ++ 4 files changed, 881 insertions(+), 1 deletion(-) create mode 100644 _scripts/contrib/schema/cve_item-v2.2.0.schema.json create mode 100644 _scripts/contrib/schema/cvss-v4.0.schema.json create mode 100755 _scripts/validate_schema-v2.2.0.bash diff --git a/.github/workflows/validate_schema.yml b/.github/workflows/validate_schema.yml index 4c0d4e79034..ece0ad22bca 100644 --- a/.github/workflows/validate_schema.yml +++ b/.github/workflows/validate_schema.yml @@ -19,5 +19,5 @@ jobs: - name: Install dependencies run: npm install -g ajv-cli && npm install -g ajv-formats - name: Run json schema validation via ajv - run: bash _scripts/validate_schema-v2.0.bash + run: bash _scripts/validate_schema-v2.2.0.bash shell: bash diff --git a/_scripts/contrib/schema/cve_item-v2.2.0.schema.json b/_scripts/contrib/schema/cve_item-v2.2.0.schema.json new file mode 100644 index 00000000000..aed659e56f6 --- /dev/null +++ b/_scripts/contrib/schema/cve_item-v2.2.0.schema.json @@ -0,0 +1,446 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Modified JSON Schema for cve_items returned by the NVD Vulnerability Data API version 2.2.0", + "definitions": { + "cvss-v2": { + "properties": { + "source": { + "type": "string" + }, + "type": { + "enum": [ + "Primary", + "Secondary" + ] + }, + "cvssData": { + "$ref": "cvss-v2.0.schema.json" + }, + "baseSeverity": { + "type": "string" + }, + "exploitabilityScore": { + "$ref": "#/definitions/def_subscore" + }, + "impactScore": { + "$ref": "#/definitions/def_subscore" + }, + "acInsufInfo": { + "type": "boolean" + }, + "obtainAllPrivilege": { + "type": "boolean" + }, + "obtainUserPrivilege": { + "type": "boolean" + }, + "obtainOtherPrivilege": { + "type": "boolean" + }, + "userInteractionRequired": { + "type": "boolean" + } + }, + "required": [ + "source", + "type", + "cvssData" + ], + "additionalProperties": false + }, + "cvss-v30": { + "properties": { + "source": { + "type": "string" + }, + "type": { + "enum": [ + "Primary", + "Secondary" + ] + }, + "cvssData": { + "$ref": "cvss-v3.0.schema.json" + }, + "exploitabilityScore": { + "$ref": "#/definitions/def_subscore" + }, + "impactScore": { + "$ref": "#/definitions/def_subscore" + } + }, + "required": [ + "source", + "type", + "cvssData" + ], + "additionalProperties": false + }, + "cvss-v31": { + "properties": { + "source": { + "type": "string" + }, + "type": { + "enum": [ + "Primary", + "Secondary" + ] + }, + "cvssData": { + "$ref": "cvss-v3.1.schema.json" + }, + "exploitabilityScore": { + "$ref": "#/definitions/def_subscore" + }, + "impactScore": { + "$ref": "#/definitions/def_subscore" + } + }, + "required": [ + "source", + "type", + "cvssData" + ], + "additionalProperties": false + }, + "cvss-v40": { + "properties": { + "source": { + "type": "string" + }, + "type": { + "enum": [ + "Primary", + "Secondary" + ] + }, + "cvssData": { + "$ref": "cvss-v4.0.schema.json" + } + }, + "required": [ + "source", + "type", + "cvssData" + ], + "additionalProperties": false + }, + "cve_id": { + "type": "string", + "pattern": "^CVE-[0-9]{4}-[0-9]{4,}$" + }, + "lang_string": { + "type": "object", + "properties": { + "lang": { + "type": "string" + }, + "value": { + "type": "string", + "maxLength": 4096 + } + }, + "required": [ + "lang", + "value" + ], + "additionalProperties": false + }, + "reference": { + "type": "object", + "properties": { + "url": { + "maxLength": 500, + "type": "string", + "pattern": "^(ftp|http)s?://\\S+$" + }, + "source": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "url" + ] + }, + "vendorComment": { + "type": "object", + "properties": { + "organization": { + "type": "string" + }, + "comment": { + "type": "string" + }, + "lastModified": { + "type": "string", + "format": "iso-date-time" + } + }, + "required": [ + "organization", + "comment", + "lastModified" + ], + "additionalProperties": false + }, + "weakness": { + "properties": { + "source": { + "type": "string" + }, + "type": { + "type": "string" + }, + "description": { + "type": "array", + "minItems": 0, + "items": { + "$ref": "#/definitions/lang_string" + } + } + }, + "required": [ + "source", + "type", + "description" + ], + "additionalProperties": false + }, + "config": { + "properties": { + "operator": { + "type": "string", + "enum": [ + "AND", + "OR" + ] + }, + "negate": { + "type": "boolean" + }, + "nodes": { + "type": "array", + "items": { + "$ref": "#/definitions/node" + } + } + }, + "required": [ + "nodes" + ] + }, + "node": { + "description": "Defines a configuration node in an NVD applicability statement.", + "properties": { + "operator": { + "type": "string", + "enum": [ + "AND", + "OR" + ] + }, + "negate": { + "type": "boolean" + }, + "cpeMatch": { + "type": "array", + "items": { + "$ref": "#/definitions/cpe_match" + } + } + }, + "required": [ + "operator", + "cpeMatch" + ] + }, + "cpe_match": { + "description": "CPE match string or range", + "type": "object", + "properties": { + "vulnerable": { + "type": "boolean" + }, + "criteria": { + "type": "string" + }, + "matchCriteriaId": { + "type": "string", + "format": "uuid" + }, + "versionStartExcluding": { + "type": "string" + }, + "versionStartIncluding": { + "type": "string" + }, + "versionEndExcluding": { + "type": "string" + }, + "versionEndIncluding": { + "type": "string" + } + }, + "required": [ + "vulnerable", + "criteria", + "matchCriteriaId" + ] + }, + "def_subscore": { + "description": "CVSS subscore.", + "type": "number", + "minimum": 0, + "maximum": 10 + } + }, + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/cve_id" + }, + "sourceIdentifier": { + "type": "string" + }, + "vulnStatus": { + "type": "string" + }, + "published": { + "type": "string", + "format": "iso-date-time" + }, + "lastModified": { + "type": "string", + "format": "iso-date-time" + }, + "evaluatorComment": { + "type": "string" + }, + "evaluatorSolution": { + "type": "string" + }, + "evaluatorImpact": { + "type": "string" + }, + "cisaExploitAdd": { + "type": "string", + "format": "date" + }, + "cisaActionDue": { + "type": "string", + "format": "date" + }, + "cisaRequiredAction": { + "type": "string" + }, + "cisaVulnerabilityName": { + "type": "string" + }, + "cveTags": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "sourceIdentifier": { + "description": "The email address or UUID of the source that contributed the information", + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "unsupported-when-assigned", + "exclusively-hosted-service", + "disputed" + ] + } + } + } + } + ] + }, + "descriptions": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/lang_string" + } + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/reference" + }, + "maxItems": 500, + "minItems": 0 + }, + "metrics": { + "description": "Metric scores for a vulnerability as found on NVD.", + "type": "object", + "properties": { + "cvssMetricV40": { + "description": "CVSS V4.0 score.", + "type": "array", + "items": { + "$ref": "#/definitions/cvss-v40" + } + }, + "cvssMetricV31": { + "description": "CVSS V3.1 score.", + "type": "array", + "items": { + "$ref": "#/definitions/cvss-v31" + } + }, + "cvssMetricV30": { + "description": "CVSS V3.0 score.", + "type": "array", + "items": { + "$ref": "#/definitions/cvss-v30" + } + }, + "cvssMetricV2": { + "description": "CVSS V2.0 score.", + "type": "array", + "items": { + "$ref": "#/definitions/cvss-v2" + } + } + } + }, + "weaknesses": { + "type": "array", + "items": { + "$ref": "#/definitions/weakness" + } + }, + "configurations": { + "type": "array", + "items": { + "$ref": "#/definitions/config" + } + }, + "vendorComments": { + "type": "array", + "items": { + "$ref": "#/definitions/vendorComment" + } + } + }, + "required": [ + "id", + "published", + "lastModified", + "references", + "descriptions" + ] +} diff --git a/_scripts/contrib/schema/cvss-v4.0.schema.json b/_scripts/contrib/schema/cvss-v4.0.schema.json new file mode 100644 index 00000000000..c802c696226 --- /dev/null +++ b/_scripts/contrib/schema/cvss-v4.0.schema.json @@ -0,0 +1,387 @@ +{ + "license": [ + "Copyright (c) 2023, FIRST.ORG, INC.", + "All rights reserved.", + "", + "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the ", + "following conditions are met:", + "1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following ", + " disclaimer.", + "2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the ", + " following disclaimer in the documentation and/or other materials provided with the distribution.", + "3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote ", + " products derived from this software without specific prior written permission.", + "", + "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, ", + "INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ", + "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ", + "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ", + "SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ", + "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ", + "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ], + + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "JSON Schema for Common Vulnerability Scoring System version 4.0", + "$id": "cvss-v4.0.schema.json", + "type": "object", + "definitions": { + "attackVectorType": { + "type": "string", + "enum": [ "NETWORK", "ADJACENT", "LOCAL", "PHYSICAL" ] + }, + "modifiedAttackVectorType": { + "type": "string", + "enum": [ "NETWORK", "ADJACENT", "LOCAL", "PHYSICAL", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "attackComplexityType": { + "type": "string", + "enum": [ "HIGH", "LOW" ] + }, + "modifiedAttackComplexityType": { + "type": "string", + "enum": [ "HIGH", "LOW", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "attackRequirementsType": { + "type": "string", + "enum": [ "NONE", "PRESENT" ] + }, + "modifiedAttackRequirementsType": { + "type": "string", + "enum": [ "NONE", "PRESENT", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "privilegesRequiredType": { + "type": "string", + "enum": [ "HIGH", "LOW", "NONE" ] + }, + "modifiedPrivilegesRequiredType": { + "type": "string", + "enum": [ "HIGH", "LOW", "NONE", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "userInteractionType": { + "type": "string", + "enum": [ "NONE", "PASSIVE", "ACTIVE" ] + }, + "modifiedUserInteractionType": { + "type": "string", + "enum": [ "NONE", "PASSIVE", "ACTIVE", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "vulnCiaType": { + "type": "string", + "enum": [ "NONE", "LOW", "HIGH" ] + }, + "modifiedVulnCiaType": { + "type": "string", + "enum": [ "NONE", "LOW", "HIGH", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "subCiaType": { + "type": "string", + "enum": [ "NONE", "LOW", "HIGH" ] + }, + "modifiedSubCType": { + "type": "string", + "enum": [ "NEGLIGIBLE", "LOW", "HIGH", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "modifiedSubIaType": { + "type": "string", + "enum": [ "NEGLIGIBLE", "LOW", "HIGH", "SAFETY", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "exploitMaturityType": { + "type": "string", + "enum": [ "UNREPORTED", "PROOF_OF_CONCEPT", "ATTACKED", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "ciaRequirementType": { + "type": "string", + "enum": [ "LOW", "MEDIUM", "HIGH", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "safetyType": { + "type": "string", + "enum": [ "NEGLIGIBLE", "PRESENT", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "automatableType": { + "type": "string", + "enum": [ "NO", "YES", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "recoveryType": { + "type": "string", + "enum": [ "AUTOMATIC", "USER", "IRRECOVERABLE", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "valueDensityType": { + "type": "string", + "enum": [ "DIFFUSE", "CONCENTRATED", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "vulnerabilityResponseEffortType": { + "type": "string", + "enum": [ "LOW", "MODERATE", "HIGH", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "providerUrgencyType": { + "type": "string", + "enum": [ "CLEAR", "GREEN", "AMBER", "RED", "NOT_DEFINED" ], + "default": "NOT_DEFINED" + }, + "noneScoreType": { + "type": "number", + "minimum": 0.0, + "maximum": 0.0 + }, + "lowScoreType": { + "type": "number", + "minimum": 0.1, + "maximum": 3.9, + "multipleOf": 0.1 + }, + "mediumScoreType": { + "type": "number", + "minimum": 4.0, + "maximum": 6.9, + "multipleOf": 0.1 + }, + "highScoreType": { + "type": "number", + "minimum": 7.0, + "maximum": 8.9, + "multipleOf": 0.1 + }, + "criticalScoreType": { + "type": "number", + "minimum": 9.0, + "maximum": 10, + "multipleOf": 0.1 + }, + "noneSeverityType": { + "const": "NONE" + }, + "lowSeverityType": { + "const": "LOW" + }, + "mediumSeverityType": { + "const": "MEDIUM" + }, + "highSeverityType": { + "const": "HIGH" + }, + "criticalSeverityType": { + "const": "CRITICAL" + } + }, + "properties": { + "version": { + "description": "CVSS Version", + "type": "string", + "enum": [ "4.0" ] + }, + "vectorString": { + "type": "string", + "pattern": "^CVSS:4[.]0\/AV:[NALP]\/AC:[LH]\/AT:[NP]\/PR:[NLH]\/UI:[NPA]\/VC:[HLN]\/VI:[HLN]\/VA:[HLN]\/SC:[HLN]\/SI:[HLN]\/SA:[HLN](\/E:[XAPU])?(\/CR:[XHML])?(\/IR:[XHML])?(\/AR:[XHML])?(\/MAV:[XNALP])?(\/MAC:[XLH])?(\/MAT:[XNP])?(\/MPR:[XNLH])?(\/MUI:[XNPA])?(\/MVC:[XNLH])?(\/MVI:[XNLH])?(\/MVA:[XNLH])?(\/MSC:[XNLH])?(\/MSI:[XNLHS])?(\/MSA:[XNLHS])?(\/S:[XNP])?(\/AU:[XNY])?(\/R:[XAUI])?(\/V:[XDC])?(\/RE:[XLMH])?(\/U:(X|Clear|Green|Amber|Red))?$" + }, + "attackVector": { "$ref": "#/definitions/attackVectorType" }, + "attackComplexity": { "$ref": "#/definitions/attackComplexityType" }, + "attackRequirements": { "$ref": "#/definitions/attackRequirementsType" }, + "privilegesRequired": { "$ref": "#/definitions/privilegesRequiredType" }, + "userInteraction": { "$ref": "#/definitions/userInteractionType" }, + "vulnConfidentialityImpact": { "$ref": "#/definitions/vulnCiaType" }, + "vulnIntegrityImpact": { "$ref": "#/definitions/vulnCiaType" }, + "vulnAvailabilityImpact": { "$ref": "#/definitions/vulnCiaType" }, + "subConfidentialityImpact": { "$ref": "#/definitions/subCiaType" }, + "subIntegrityImpact": { "$ref": "#/definitions/subCiaType" }, + "subAvailabilityImpact": { "$ref": "#/definitions/subCiaType" }, + "exploitMaturity": { "$ref": "#/definitions/exploitMaturityType" }, + "confidentialityRequirement": { "$ref": "#/definitions/ciaRequirementType" }, + "integrityRequirement": { "$ref": "#/definitions/ciaRequirementType" }, + "availabilityRequirement": { "$ref": "#/definitions/ciaRequirementType" }, + "modifiedAttackVector": { "$ref": "#/definitions/modifiedAttackVectorType" }, + "modifiedAttackComplexity": { "$ref": "#/definitions/modifiedAttackComplexityType" }, + "modifiedAttackRequirements": { "$ref": "#/definitions/modifiedAttackRequirementsType" }, + "modifiedPrivilegesRequired": { "$ref": "#/definitions/modifiedPrivilegesRequiredType" }, + "modifiedUserInteraction": { "$ref": "#/definitions/modifiedUserInteractionType" }, + "modifiedVulnConfidentialityImpact": { "$ref": "#/definitions/modifiedVulnCiaType" }, + "modifiedVulnIntegrityImpact": { "$ref": "#/definitions/modifiedVulnCiaType" }, + "modifiedVulnAvailabilityImpact": { "$ref": "#/definitions/modifiedVulnCiaType" }, + "modifiedSubConfidentialityImpact": { "$ref": "#/definitions/modifiedSubCType" }, + "modifiedSubIntegrityImpact": { "$ref": "#/definitions/modifiedSubIaType" }, + "modifiedSubAvailabilityImpact": { "$ref": "#/definitions/modifiedSubIaType" }, + "Safety": { "$ref": "#/definitions/safetyType" }, + "Automatable": { "$ref": "#/definitions/automatableType" }, + "Recovery": { "$ref": "#/definitions/recoveryType" }, + "valueDensity": { "$ref": "#/definitions/valueDensityType" }, + "vulnerabilityResponseEffort": { "$ref": "#/definitions/vulnerabilityResponseEffortType" }, + "providerUrgency": { "$ref": "#/definitions/providerUrgencyType" } + }, + "allOf": [ + { + "anyOf": [{ + "properties": { + "baseScore" : { + "$ref": "#/definitions/noneScoreType" + }, + "baseSeverity" : { + "$ref": "#/definitions/noneSeverityType" + } + } + }, + { + "properties": { + "baseScore" : { + "$ref": "#/definitions/lowScoreType" + }, + "baseSeverity" : { + "$ref": "#/definitions/lowSeverityType" + } + } + }, + { + "properties": { + "baseScore" : { + "$ref": "#/definitions/mediumScoreType" + }, + "baseSeverity" : { + "$ref": "#/definitions/mediumSeverityType" + } + } + }, + { + "properties": { + "baseScore" : { + "$ref": "#/definitions/highScoreType" + }, + "baseSeverity" : { + "$ref": "#/definitions/highSeverityType" + } + } + }, + { + "properties": { + "baseScore" : { + "$ref": "#/definitions/criticalScoreType" + }, + "baseSeverity" : { + "$ref": "#/definitions/criticalSeverityType" + } + } + }] + }, + { + "anyOf": [{ + "properties": { + "threatScore" : { + "$ref": "#/definitions/noneScoreType" + }, + "threatSeverity" : { + "$ref": "#/definitions/noneSeverityType" + } + } + }, + { + "properties": { + "threatScore" : { + "$ref": "#/definitions/lowScoreType" + }, + "threatSeverity" : { + "$ref": "#/definitions/lowSeverityType" + } + } + }, + { + "properties": { + "threatScore" : { + "$ref": "#/definitions/mediumScoreType" + }, + "threatSeverity" : { + "$ref": "#/definitions/mediumSeverityType" + } + } + }, + { + "properties": { + "threatScore" : { + "$ref": "#/definitions/highScoreType" + }, + "threatSeverity" : { + "$ref": "#/definitions/highSeverityType" + } + } + }, + { + "properties": { + "threatScore" : { + "$ref": "#/definitions/criticalScoreType" + }, + "threatSeverity" : { + "$ref": "#/definitions/criticalSeverityType" + } + } + } + ] + }, + { + "anyOf": [ + { + "properties": { + "environmentalScore" : { + "$ref": "#/definitions/noneScoreType" + }, + "environmentalSeverity" : { + "$ref": "#/definitions/noneSeverityType" + } + } + }, + { + "properties": { + "environmentalScore" : { + "$ref": "#/definitions/lowScoreType" + }, + "environmentalSeverity" : { + "$ref": "#/definitions/lowSeverityType" + } + } + }, + { + "properties": { + "environmentalScore" : { + "$ref": "#/definitions/mediumScoreType" + }, + "environmentalSeverity" : { + "$ref": "#/definitions/mediumSeverityType" + } + } + }, + { + "properties": { + "environmentalScore" : { + "$ref": "#/definitions/highScoreType" + }, + "environmentalSeverity" : { + "$ref": "#/definitions/highSeverityType" + } + } + }, + { + "properties": { + "environmentalScore" : { + "$ref": "#/definitions/criticalScoreType" + }, + "environmentalSeverity" : { + "$ref": "#/definitions/criticalSeverityType" + } + } + } + ] + } + ], + "required": [ "version", "vectorString", "baseScore", "baseSeverity" ] +} diff --git a/_scripts/validate_schema-v2.2.0.bash b/_scripts/validate_schema-v2.2.0.bash new file mode 100755 index 00000000000..3e677bbdabd --- /dev/null +++ b/_scripts/validate_schema-v2.2.0.bash @@ -0,0 +1,47 @@ +#!/bin/bash + +script_parent=$( (cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P) || exit 1 ) +schema_path="$script_parent/contrib/schema" +cve_path="$script_parent/../" + + +print_dependency_error_and_exit() { + echo "[error] $1 not installed." + echo "this script uses ajv to validate the json files in this repository." + echo "please ensure that npm and the required packages are installed." + echo " - npm install -g ajv-cli" + echo " - npm install -g ajv-formats" + echo "[note] the above commands install the ajv packages globally." + exit 2 +} + + +if ! command -v npm &> /dev/null; then + print_dependency_error_and_exit "npm" +fi + +npm list -g ajv &> /dev/null +status=$? +if [ $status -ne 0 ]; then + print_dependency_error_and_exit "ajv-cli" +fi + +npm list -g ajv-formats &> /dev/null +status=$? +if [ $status -ne 0 ]; then + print_dependency_error_and_exit "ajv-formats" +fi + +set -euxo pipefail + +ajv validate -s "$schema_path/cve_item-v2.2.0.schema.json" \ + -d "$cve_path/CVE-*/**/*.json" \ + --strict=false \ + -r "$schema_path/cvss-v4.0.schema.json" \ + -r "$schema_path/cvss-v3.1.schema.json" \ + -r "$schema_path/cvss-v3.0.schema.json" \ + -r "$schema_path/cvss-v2.0.schema.json" \ + --all-errors \ + --errors=json \ + -c ajv-formats > /dev/null +