diff --git a/docs/reference/decision_points/cvss/index.md b/docs/reference/decision_points/cvss/index.md index 74c9fa53..f9309c0f 100644 --- a/docs/reference/decision_points/cvss/index.md +++ b/docs/reference/decision_points/cvss/index.md @@ -23,6 +23,12 @@ We have organized them into groups according to where they belong in the been refined over different versions of the CVSS specification. These versions do _not_ correspond the CVSS specification versions (2.0, 3.0, 3.1, 4.0 etc.). +### Qualitative Severity + +
+- [CVSS Qualitative Severity Rating Scale](qualitative_severity.md) +
+ ### Base Metrics
diff --git a/docs/reference/decision_points/cvss/qualitative_severity.md b/docs/reference/decision_points/cvss/qualitative_severity.md new file mode 100644 index 00000000..81be133d --- /dev/null +++ b/docs/reference/decision_points/cvss/qualitative_severity.md @@ -0,0 +1,12 @@ +# CVSS Qualitative Severity Rating Scale + +```python exec="true" idprefix="" +from ssvc.decision_points.cvss.qualitative_severity import LATEST +from ssvc.doc_helpers import example_block + +print(example_block(LATEST)) +``` + +The [CVSS Qualitative Severity Rating Scale](https://www.first.org/cvss/v4.0/specification-document#Qualitative-Severity-Rating-Scale) +is a set of labels that describe the severity of a vulnerability based on the +CVSS Score. diff --git a/mkdocs.yml b/mkdocs.yml index 1b896cf1..2e47540c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -73,6 +73,7 @@ nav: - Utility: 'reference/decision_points/utility.md' - CVSS-based decision points: - 'reference/decision_points/cvss/index.md' + - Qualitative Severity: 'reference/decision_points/cvss/qualitative_severity.md' - Base Metrics: - Attack Vector: 'reference/decision_points/cvss/attack_vector.md' - Attack Complexity: 'reference/decision_points/cvss/attack_complexity.md' diff --git a/src/ssvc/decision_points/cvss/qualitative_severity.py b/src/ssvc/decision_points/cvss/qualitative_severity.py new file mode 100644 index 00000000..23358fe7 --- /dev/null +++ b/src/ssvc/decision_points/cvss/qualitative_severity.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +""" +Provides a decision point for the [CVSS Qualitative Severity Rating Scale](https://www.first.org/cvss/v4.0/specification-document#Qualitative-Severity-Rating-Scale). +""" +# Copyright (c) 2025 Carnegie Mellon University and Contributors. +# - see Contributors.md for a full list of Contributors +# - see ContributionInstructions.md for information on how you can Contribute to this project +# Stakeholder Specific Vulnerability Categorization (SSVC) is +# licensed under a MIT (SEI)-style license, please see LICENSE.md distributed +# with this Software or contact permission@sei.cmu.edu for full terms. +# Created, in part, with funding and support from the United States Government +# (see Acknowledgments file). This program may include and/or can make use of +# certain third party source code, object code, documentation and other files +# (“Third Party Software”). See LICENSE.md for more details. +# Carnegie Mellon®, CERT® and CERT Coordination Center® are registered in the +# U.S. Patent and Trademark Office by Carnegie Mellon University + +from ssvc.decision_points import SsvcDecisionPointValue +from ssvc.decision_points.cvss.base import CvssDecisionPoint +from ssvc.decision_points.helpers import print_versions_and_diffs + +QS_NONE = SsvcDecisionPointValue( + name="None", + key="N", + description="No severity rating (0.0)", +) + +LOW = SsvcDecisionPointValue( + name="Low", + key="L", + description="Low (0.1 - 3.9)", +) +MEDIUM = SsvcDecisionPointValue( + name="Medium", + key="M", + description="Medium (4.0 - 6.9)", +) +HIGH = SsvcDecisionPointValue( + name="High", + key="H", + description="High (7.0 - 8.9)", +) +CRITICAL = SsvcDecisionPointValue( + name="Critical", + key="C", + description="Critical (9.0 - 10.0)", +) + +QUALITATIVE_SEVERITY = CvssDecisionPoint( + name="CVSS Qualitative Severity Rating Scale", + key="QS", + description="The CVSS Qualitative Severity Rating Scale provides " + "a categorical representation of a CVSS Score.", + version="1.0.0", + values=( + QS_NONE, + LOW, + MEDIUM, + HIGH, + CRITICAL, + ), +) + +VERSIONS = (QUALITATIVE_SEVERITY,) +LATEST = VERSIONS[-1] + + +def main(): + print_versions_and_diffs(VERSIONS) + + +if __name__ == "__main__": + main() diff --git a/src/ssvc/doc_helpers.py b/src/ssvc/doc_helpers.py index 6304044f..16a48bc8 100644 --- a/src/ssvc/doc_helpers.py +++ b/src/ssvc/doc_helpers.py @@ -69,10 +69,12 @@ def example_block_tabbed(dp: SsvcDecisionPoint, indent=4) -> str: return "\n".join(rows) -def example_block(dp: SsvcDecisionPoint, indent=4) -> str: +def example_block( + dp: SsvcDecisionPoint, indent: int = 4, include_json: bool = True +) -> str: """Given a decision point, return a markdown block that contains an example of the decision point.""" - indent_ = " " * 4 + indent_ = " " * indent rows = [] rows.append(f'!!! note "{dp.name} v{dp.version}"') rows.append("") @@ -81,12 +83,11 @@ def example_block(dp: SsvcDecisionPoint, indent=4) -> str: rows.append(indent_ + row) rows.append("") - rows.append( - indent_ + f'??? example "{dp.name} v{dp.version} JSON Example"' - ) - rows.append("") - for row in json_example(dp, indent=4).splitlines(): - rows.append(indent_ + row) + if include_json: + rows.append(indent_ + f'??? example "{dp.name} v{dp.version} JSON Example"') + rows.append("") + for row in json_example(dp, indent=4).splitlines(): + rows.append(indent_ + row) return "\n".join(rows)