From b441fe8303f4f0d8c0a96825ca7d88de1eb3e413 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Thu, 17 Sep 2026 17:18:23 -0500 Subject: [PATCH 1/6] Added EPSS Signed-off-by: Steve Springett --- schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json b/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json index 551c2e0df..42cf3f27d 100644 --- a/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json @@ -373,6 +373,7 @@ "CVSSv4", "OWASP", "SSVC", + "EPSS", "other" ], "meta:enum": { @@ -382,6 +383,7 @@ "CVSSv4": "Common Vulnerability Scoring System v4.0", "OWASP": "OWASP Risk Rating Methodology", "SSVC": "Stakeholder Specific Vulnerability Categorization", + "EPSS": "Exploit Prediction Scoring System", "other": "Another severity or risk scoring methodology" } }, From a859af8a906cfebbc257ecc8e68133a02a414a12 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Fri, 18 Sep 2026 15:59:42 -0500 Subject: [PATCH 2/6] Created allowance for EPSS named measurements (percentile and probability) without restricting ourselves specifically to EPSS, or future scoring systems or versions of EPSS. Signed-off-by: Steve Springett --- .../cyclonedx-vulnerability-2.0.schema.json | 164 +++++++++++++++--- 1 file changed, 142 insertions(+), 22 deletions(-) diff --git a/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json b/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json index 42cf3f27d..1c2318fb0 100644 --- a/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json +++ b/schema/2.0/model/cyclonedx-vulnerability-2.0.schema.json @@ -365,27 +365,51 @@ }, "scoreMethod": { "title": "Method", - "description": "Specifies the severity or risk scoring methodology or standard used.", - "enum": [ - "CVSSv2", - "CVSSv3", - "CVSSv31", - "CVSSv4", - "OWASP", - "SSVC", - "EPSS", - "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", - "EPSS": "Exploit Prediction Scoring System", - "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", @@ -446,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`.", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/ratingMeasure" + } }, "severity": { "$ref": "#/$defs/severity", @@ -455,16 +488,103 @@ "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" ] } + } + } + ] + }, + "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", + "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": { From 4d7182eadabf7d58548edb2a203af6defd67988e Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Thu, 17 Sep 2026 17:18:23 -0500 Subject: [PATCH 3/6] Added EPSS Signed-off-by: Steve Springett --- schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json | 2 ++ 1 file changed, 2 insertions(+) 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 d67385ee1..050b10b60 100644 --- a/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json @@ -373,6 +373,7 @@ "CVSSv4", "OWASP", "SSVC", + "EPSS", "other" ], "meta:enum": { @@ -382,6 +383,7 @@ "CVSSv4": "Common Vulnerability Scoring System v4.0", "OWASP": "OWASP Risk Rating Methodology", "SSVC": "Stakeholder Specific Vulnerability Categorization", + "EPSS": "Exploit Prediction Scoring System", "other": "Another severity or risk scoring methodology" } }, From 4dab87200db5150c212322376b88e500f3006256 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Fri, 18 Sep 2026 15:59:42 -0500 Subject: [PATCH 4/6] Created allowance for EPSS named measurements (percentile and probability) without restricting ourselves specifically to EPSS, or future scoring systems or versions of EPSS. Signed-off-by: Steve Springett --- .../cyclonedx-vulnerability-2.0.schema.json | 164 +++++++++++++++--- 1 file changed, 142 insertions(+), 22 deletions(-) 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 050b10b60..3e3be71ca 100644 --- a/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json @@ -365,27 +365,51 @@ }, "scoreMethod": { "title": "Method", - "description": "Specifies the severity or risk scoring methodology or standard used.", - "enum": [ - "CVSSv2", - "CVSSv3", - "CVSSv31", - "CVSSv4", - "OWASP", - "SSVC", - "EPSS", - "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", - "EPSS": "Exploit Prediction Scoring System", - "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", @@ -446,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`.", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/ratingMeasure" + } }, "severity": { "$ref": "#/$defs/severity", @@ -455,16 +488,103 @@ "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" ] } + } + } + ] + }, + "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", + "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": { From 754cb5958d0019068271864549c52d7dfb5faf67 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Thu, 15 Oct 2026 16:42:58 -0500 Subject: [PATCH 5/6] Apply suggestion from @jkowalleck Co-authored-by: Jan Kowalleck Signed-off-by: Steve Springett --- schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3e3be71ca..162a792ac 100644 --- a/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json @@ -524,7 +524,7 @@ } }, "then": { - "not": { "required": [ "score" ] } + "not": { "required": [ "score" ], "properties": { "score": true } } } } ] From 5c34d1adc17227bd2ec396e03e333ddce4ac7985 Mon Sep 17 00:00:00 2001 From: Steve Springett Date: Thu, 15 Oct 2026 16:46:38 -0500 Subject: [PATCH 6/6] Minor corrections Signed-off-by: Steve Springett --- schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 3e3be71ca..64d7e415d 100644 --- a/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json +++ b/schema/2.0/modules/cyclonedx-vulnerability-2.0.schema.json @@ -475,7 +475,7 @@ "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`.", + "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" @@ -548,6 +548,7 @@ "enum": [ "probability", "percentile", + "confidence", "rank" ], "meta:enum": {