Skip to content

Commit

Permalink
Add python decision points for critical software, high value assets, …
Browse files Browse the repository at this point in the history
…and in KEV (#346)

* move away from deepcopy to just rebuilding decision points from scratch

* add iterator to decision point group

* add critical software and high value asset decision points

- update unit tests

* avoid deepcopy

* don't need to specify namespace in object

* add "in KEV" decision point to address #317
  • Loading branch information
ahouseholder authored Oct 17, 2023
1 parent 798ff57 commit e2583ec
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 11 deletions.
49 changes: 49 additions & 0 deletions src/ssvc/decision_points/critical_software.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env python
"""
Provides an SSVC decision point for critical software designation.
"""
# Copyright (c) 2023 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.base import SsvcDecisionPoint, SsvcDecisionPointValue

YES = SsvcDecisionPointValue(
name="Yes",
key="Y",
description="System meets a critical software definition.",
)

NO = SsvcDecisionPointValue(
name="No",
key="N",
description="System does not meet a critical software definition.",
)

CRITICAL_SOFTWARE_1 = SsvcDecisionPoint(
name="Critical Software",
description="Denotes whether a system meets a critical software definition.",
key="CS",
version="1.0.0",
values=(
NO,
YES,
),
)


def main():
print(CRITICAL_SOFTWARE_1.to_json(indent=2))


if __name__ == "__main__":
main()
49 changes: 49 additions & 0 deletions src/ssvc/decision_points/high_value_asset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env python
"""
Models a high value asset as a decision point.
"""
# Copyright (c) 2023 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.base import SsvcDecisionPoint, SsvcDecisionPointValue

YES = SsvcDecisionPointValue(
name="Yes",
key="Y",
description="System meets a high value asset definition.",
)

NO = SsvcDecisionPointValue(
name="No",
key="N",
description="System does not meet a high value asset definition.",
)

HIGH_VALUE_ASSET_1 = SsvcDecisionPoint(
name="High Value Asset",
description="Denotes whether a system meets a high value asset definition.",
key="HVA",
version="1.0.0",
values=(
NO,
YES,
),
)


def main():
print(HIGH_VALUE_ASSET_1.to_json(indent=2))


if __name__ == "__main__":
main()
49 changes: 49 additions & 0 deletions src/ssvc/decision_points/in_kev.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env python
"""
Provides a decision point representing whether a vulnerability is in the CISA Known Exploited Vulnerabilities (KEV) list.
"""
# Copyright (c) 2023 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.base import SsvcDecisionPoint, SsvcDecisionPointValue

YES = SsvcDecisionPointValue(
name="Yes",
key="Y",
description="Vulnerability is listed in KEV.",
)

NO = SsvcDecisionPointValue(
name="No",
key="N",
description="Vulnerability is not listed in KEV.",
)

IN_KEV_1 = SsvcDecisionPoint(
name="In KEV",
description="Denotes whether a vulnerability is in the CISA Known Exploited Vulnerabilities (KEV) list.",
key="KEV",
version="1.0.0",
values=(
NO,
YES,
),
)


def main():
print(IN_KEV_1.to_json(indent=2))


if __name__ == "__main__":
main()
11 changes: 7 additions & 4 deletions src/ssvc/decision_points/mission_impact.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
author: adh
created_at: 9/21/23 10:20 AM
"""
from copy import deepcopy

from ssvc.decision_points.base import SsvcDecisionPoint, SsvcDecisionPointValue

Expand Down Expand Up @@ -61,9 +60,13 @@
)

# SSVC v2.1 combined None and Non-Essential Degraded into a single value
MISSION_IMPACT_2 = deepcopy(MISSION_IMPACT_1)
MISSION_IMPACT_2.version = "2.0.0"
MISSION_IMPACT_2.values = (DEGRADED, MEF_CRIPPLED, MEF_FAILURE, MISSION_FAILURE)
MISSION_IMPACT_2 = SsvcDecisionPoint(
name="Mission Impact",
description="Impact on Mission Essential Functions of the Organization",
key="MI",
version="2.0.0",
values=(DEGRADED, MEF_CRIPPLED, MEF_FAILURE, MISSION_FAILURE),
)


def main():
Expand Down
1 change: 0 additions & 1 deletion src/ssvc/decision_points/safety_impact.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
author: adh
created_at: 9/21/23 10:05 AM
"""
from copy import deepcopy

from ssvc.decision_points.base import SsvcDecisionPoint, SsvcDecisionPointValue

Expand Down
11 changes: 7 additions & 4 deletions src/ssvc/decision_points/system_exposure.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
author: adh
created_at: 9/21/23 10:16 AM
"""
from copy import deepcopy
from ssvc.decision_points.base import SsvcDecisionPoint, SsvcDecisionPointValue

EXP_UNAVOIDABLE = SsvcDecisionPointValue(
Expand Down Expand Up @@ -45,9 +44,13 @@
)

# EXP_OPEN is just a rename of EXP_UNAVOIDABLE
EXP_OPEN = deepcopy(EXP_UNAVOIDABLE)
EXP_OPEN.name = "Open"
EXP_OPEN.key = "O"
EXP_OPEN = SsvcDecisionPointValue(
name="Open",
key="O",
description="Internet or another widely accessible network where access cannot plausibly be restricted or "
"controlled (e.g., DNS servers, web servers, VOIP servers, email servers)",
)


SYSTEM_EXPOSURE_1_0_1 = SsvcDecisionPoint(
name="System Exposure",
Expand Down
1 change: 0 additions & 1 deletion src/ssvc/decision_points/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
author: adh
created_at: 9/21/23 9:55 AM
"""
from copy import deepcopy

from ssvc.decision_points.base import SsvcDecisionPoint, SsvcDecisionPointValue

Expand Down
3 changes: 3 additions & 0 deletions src/ssvc/dp_groups/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class SsvcDecisionPointGroup(_Base, _Versioned):

decision_points: Tuple[SsvcDecisionPoint]

def __iter__(self):
return iter(self.decision_points)


def get_all_decision_points_from(
glist: list[SsvcDecisionPointGroup],
Expand Down
26 changes: 25 additions & 1 deletion src/test/test_schema.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# Copyright (c) 2023 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

import json
import logging
import unittest
Expand All @@ -6,7 +19,9 @@

import ssvc.decision_points # noqa F401
from ssvc.decision_points.base import REGISTERED_DECISION_POINTS

from ssvc.decision_points.critical_software import CRITICAL_SOFTWARE_1 # noqa
from ssvc.decision_points.high_value_asset import HIGH_VALUE_ASSET_1 # noqa
from ssvc.decision_points.in_kev import IN_KEV_1
# importing these causes the decision points to register themselves
from ssvc.dp_groups.v1 import SSVCv1 # noqa
from ssvc.dp_groups.v2 import SSVCv2 # noqa
Expand All @@ -31,6 +46,15 @@ def setUp(self) -> None:
logger.addHandler(hdlr)
self.logger = logger

def test_confirm_registered_decision_points(self):
dps = list(REGISTERED_DECISION_POINTS)
self.assertGreater(len(dps), 0)

extras = [CRITICAL_SOFTWARE_1, HIGH_VALUE_ASSET_1, IN_KEV_1]
for dpg in [SSVCv1, SSVCv2, SSVCv2_1, extras]:
for dp in dpg:
self.assertIn(dp, REGISTERED_DECISION_POINTS)

def test_decision_point_validation(self):
# path relative to top level of repo
schema_file = find_schema("data/schema/Decision_Point.schema.json")
Expand Down

0 comments on commit e2583ec

Please sign in to comment.