diff --git a/.github/workflows/validate_schema.yml b/.github/workflows/validate_schema.yml index ece0ad22bca..3c7642a274d 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.2.0.bash + run: bash _scripts/validate_schema-v2.2.3.bash shell: bash diff --git a/_scripts/contrib/schema/cve_item-v2.2.3.schema.json b/_scripts/contrib/schema/cve_item-v2.2.3.schema.json new file mode 100644 index 00000000000..9c790a22887 --- /dev/null +++ b/_scripts/contrib/schema/cve_item-v2.2.3.schema.json @@ -0,0 +1,445 @@ +{ + "$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.3", + "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": { + "type": "string", + "format": "uri", + "minLength": 1, + "maxLength": 2048 + }, + "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" + } + }, + "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/validate_schema-v2.2.3.bash b/_scripts/validate_schema-v2.2.3.bash new file mode 100755 index 00000000000..1c2d8455691 --- /dev/null +++ b/_scripts/validate_schema-v2.2.3.bash @@ -0,0 +1,49 @@ +#!/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.3.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" \ + --errors=json \ + --all-errors \ + --multiple-of-precision=1 \ + -c ajv-formats > /dev/null + +