Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CVSS Qualitative Severity Rating Scale decision point #712

Merged
merged 4 commits into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/reference/decision_points/cvss/qualitative_severity.md
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
73 changes: 73 additions & 0 deletions src/ssvc/decision_points/cvss/qualitative_severity.py
Original file line number Diff line number Diff line change
@@ -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",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lingering CVSS versioning question on my mind. May be it should be an issue. The CVSS V4 is sometime represented with namespace version combo of cvss and 3.0.1 like in ATTACK_VECTOR_3_0_1 (in src/ssvc/decision_points/cvss/attack_vector.py file) for CVSS v4 Attack Vector - can we track mapping this way? This seems to be the case in this PR as well where CVSSv4 Quality metric shows us as version 1.0.0 with names space cvss

Copy link
Contributor Author

@ahouseholder ahouseholder Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The decision point versions are the decision point versions. They have no connection to CVSS versions.

The qualitative severity scale was added in CVSS v3.0 and has not changed (search each of these for "qualitative severity" to confirm), so by our decision point versioning rules, this one is 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()
17 changes: 9 additions & 8 deletions src/ssvc/doc_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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("")
Expand All @@ -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)

Expand Down