diff --git a/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json b/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json index 78fb2981c..50c837d9b 100644 --- a/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json @@ -365,25 +365,51 @@ }, "scoreMethod": { "title": "Method", - "description": "Specifies the severity or risk scoring methodology or standard used.", - "enum": [ - "CVSSv2", - "CVSSv3", - "CVSSv31", - "CVSSv4", - "OWASP", - "SSVC", - "other" - ], - "meta:enum": { - "CVSSv2": "Common Vulnerability Scoring System v2.0", - "CVSSv3": "Common Vulnerability Scoring System v3.0", - "CVSSv31": "Common Vulnerability Scoring System v3.1", - "CVSSv4": "Common Vulnerability Scoring System v4.0", - "OWASP": "OWASP Risk Rating Methodology", - "SSVC": "Stakeholder Specific Vulnerability Categorization", - "other": "Another severity or risk scoring methodology" - } + "description": "Specifies the severity or risk scoring methodology or standard used. Use the custom option for methodologies not listed.", + "oneOf": [ + { + "title": "Predefined Method", + "enum": [ + "CVSSv2", + "CVSSv3", + "CVSSv31", + "CVSSv4", + "OWASP", + "SSVC", + "EPSS" + ], + "meta:enum": { + "CVSSv2": "Common Vulnerability Scoring System v2.0.", + "CVSSv3": "Common Vulnerability Scoring System v3.0.", + "CVSSv31": "Common Vulnerability Scoring System v3.1.", + "CVSSv4": "Common Vulnerability Scoring System v4.0.", + "OWASP": "OWASP Risk Rating Methodology.", + "SSVC": "Stakeholder Specific Vulnerability Categorization.", + "EPSS": "Exploit Prediction Scoring System." + } + }, + { + "title": "Custom Method", + "type": "object", + "required": [ + "name" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "The name of the custom scoring methodology." + }, + "description": { + "type": "string", + "title": "Description", + "description": "A description of the custom scoring methodology." + } + } + } + ] }, "impactAnalysisState": { "title": "Impact Analysis State", @@ -444,7 +470,16 @@ "score": { "type": "number", "title": "Score", - "description": "The numerical score of the rating." + "description": "The numerical score of the rating, on the scale defined by the method. Methods that do not produce a single score on that scale record their values in `measures` instead." + }, + "measures": { + "type": "array", + "title": "Measures", + "description": "Named values produced by the scoring method. Methods that emit more than one value, or a value on a scale unlike the primary score, record each value here rather than in `score`. Each measure name shall appear at most once within a rating.", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/ratingMeasure" + } }, "severity": { "$ref": "#/$defs/severity", @@ -453,16 +488,104 @@ "method": { "$ref": "#/$defs/scoreMethod" }, + "methodVersion": { + "type": "string", + "minLength": 1, + "title": "Method Version", + "description": "The version or revision of the scoring method that produced this rating, for methods that version themselves independently of the value recorded in `method`.", + "examples": [ + "v2025.03.14" + ] + }, "vector": { "type": "string", "title": "Vector", "description": "Textual representation of the metric values used to score the vulnerability" }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp", + "description": "The date and time the rating was produced or observed. Relevant to methods whose scores are recalculated on a schedule." + }, "justification": { "type": "string", "title": "Justification", "description": "A reason for rating the vulnerability as it was" } + }, + "allOf": [ + { + "$comment": "The Exploit Prediction Scoring System reports probabilities and ranks rather than a score on the severity scale that `score` carries, so its values are recorded as named measures. Constraining the form keeps an EPSS probability from being read or ordered as though it were a severity score.", + "if": { + "required": [ "method" ], + "properties": { + "method": { "const": "EPSS" } + } + }, + "then": { + "not": { "required": [ "score" ], "properties": { "score": true } } + } + } + ] + }, + "ratingMeasure": { + "type": "object", + "title": "Rating Measure", + "description": "A named value produced by a scoring method. The set of names a method emits is defined by that method.", + "required": [ + "name", + "value" + ], + "additionalProperties": false, + "properties": { + "name": { + "title": "Name", + "description": "The name of the measure, given as a predefined name or as a custom name defined by the scoring method.", + "oneOf": [ + { + "title": "Predefined Measure", + "enum": [ + "probability", + "percentile", + "confidence", + "rank" + ], + "meta:enum": { + "probability": "The likelihood of the scored outcome within the period defined by the method, expressed as a decimal from 0 to 1.", + "percentile": "The proportion of the scored population at or below this subject, expressed as a decimal from 0 to 1.", + "confidence": "The degree of certainty in the score, expressed as a decimal from 0 to 1.", + "rank": "The position of the subject within the scored population." + } + }, + { + "title": "Custom Measure", + "type": "object", + "required": [ + "name" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1, + "title": "Name", + "description": "The name of the custom measure." + }, + "description": { + "type": "string", + "title": "Description", + "description": "A description of the custom measure." + } + } + } + ] + }, + "value": { + "type": "number", + "title": "Value", + "description": "The numeric value of the measure." + } } }, "vulnerabilitySource": {