Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions docs/reference/decision_points/cvss/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

<div class="grid cards" markdown>
- [CVSS Qualitative Severity Rating Scale](qualitative_severity.md)
</div>

### Base Metrics

<div class="grid cards" markdown>
Expand Down
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 [email protected] 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