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
12 changes: 9 additions & 3 deletions src/SSVC_csv-to-latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@ def print_forest_options(
"""
)
location.write(pri5string)
location.write("}\n") # close the last tikzset; forestset is already closed
location.write(
"}\n"
) # close the last tikzset; forestset is already closed


def begin_forest(location):
Expand Down Expand Up @@ -348,7 +350,9 @@ def main():
if path[i] not in dpoint_values[i]:
dpoint_values[i].append(path[i])
for i in range(depth):
dpoint_values[i].sort(key=lambda j: sort_order[i].index(j), reverse=True)
dpoint_values[i].sort(
key=lambda j: sort_order[i].index(j), reverse=True
)
# reverse because the latex will flip it again
# loop twice so we don't sort every time we check a new path

Expand Down Expand Up @@ -380,7 +384,9 @@ def main():
del tmp_path[-1]
i = i - 1
ofile.write(latex_brace_close) # close each latex brace
del tmp_path[-1] # every time we close a brace, update the path to reflect
del tmp_path[
-1
] # every time we close a brace, update the path to reflect
else: # "Normal" case
if counts[i] == len(dpoint_values[i]):
try:
Expand Down
16 changes: 12 additions & 4 deletions src/ssvc/csv_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ def _imp_df(column_names: list, importances: list) -> pd.DataFrame:
a dataframe of feature importances
"""
df = (
pd.DataFrame({"feature": column_names, "feature_importance": importances})
pd.DataFrame(
{"feature": column_names, "feature_importance": importances}
)
.sort_values("feature_importance", ascending=False)
.reset_index(drop=True)
)
Expand Down Expand Up @@ -184,7 +186,9 @@ def _perm_feat_imp(model, x, y):

def _parse_args(args) -> argparse.Namespace:
# parse command line
parser = argparse.ArgumentParser(description="Analyze an SSVC tree csv file")
parser = argparse.ArgumentParser(
description="Analyze an SSVC tree csv file"
)
parser.add_argument(
"csvfile", metavar="csvfile", type=str, help="the csv file to analyze"
)
Expand Down Expand Up @@ -371,8 +375,12 @@ def check_topological_order(df, target):
for u in H.nodes:
H.nodes[u]["outcome"] = G.nodes[u]["outcome"]

logger.debug(f"Original graph: {len(G.nodes)} nodes with {len(G.edges)} edges")
logger.debug(f"Reduced graph: {len(H.nodes)} nodes with {len(H.edges)} edges")
logger.debug(
f"Original graph: {len(G.nodes)} nodes with {len(G.edges)} edges"
)
logger.debug(
f"Reduced graph: {len(H.nodes)} nodes with {len(H.edges)} edges"
)

problems = []
# check if the outcome is topologically sorted
Expand Down
7 changes: 6 additions & 1 deletion src/ssvc/decision_points/cvss/attack_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,12 @@
),
)

versions = [ACCESS_VECTOR_1, ACCESS_VECTOR_2, ATTACK_VECTOR_3, ATTACK_VECTOR_3_0_1]
versions = [
ACCESS_VECTOR_1,
ACCESS_VECTOR_2,
ATTACK_VECTOR_3,
ATTACK_VECTOR_3_0_1,
]


def main():
Expand Down
6 changes: 5 additions & 1 deletion src/ssvc/decision_points/cvss/availability_impact.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@
),
)

versions = [AVAILABILITY_IMPACT_1, AVAILABILITY_IMPACT_2, AVAILABILITY_IMPACT_2_0_1]
versions = [
AVAILABILITY_IMPACT_1,
AVAILABILITY_IMPACT_2,
AVAILABILITY_IMPACT_2_0_1,
]


def main():
Expand Down
5 changes: 4 additions & 1 deletion src/ssvc/decision_points/cvss/availability_requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
# U.S. Patent and Trademark Office by Carnegie Mellon University

from ssvc.decision_points.base import SsvcDecisionPointValue
from ssvc.decision_points.cvss._not_defined import NOT_DEFINED_ND, NOT_DEFINED_X
from ssvc.decision_points.cvss._not_defined import (
NOT_DEFINED_ND,
NOT_DEFINED_X,
)
from ssvc.decision_points.cvss.base import CvssDecisionPoint
from ssvc.decision_points.helpers import print_versions_and_diffs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
# U.S. Patent and Trademark Office by Carnegie Mellon University

from ssvc.decision_points.base import SsvcDecisionPointValue
from ssvc.decision_points.cvss._not_defined import NOT_DEFINED_ND, NOT_DEFINED_X
from ssvc.decision_points.cvss._not_defined import (
NOT_DEFINED_ND,
NOT_DEFINED_X,
)
from ssvc.decision_points.cvss.base import CvssDecisionPoint
from ssvc.decision_points.helpers import print_versions_and_diffs

Expand Down
5 changes: 4 additions & 1 deletion src/ssvc/decision_points/cvss/exploitability.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
# U.S. Patent and Trademark Office by Carnegie Mellon University

from ssvc.decision_points.base import SsvcDecisionPointValue
from ssvc.decision_points.cvss._not_defined import NOT_DEFINED_ND, NOT_DEFINED_X
from ssvc.decision_points.cvss._not_defined import (
NOT_DEFINED_ND,
NOT_DEFINED_X,
)
from ssvc.decision_points.cvss.base import CvssDecisionPoint
from ssvc.decision_points.helpers import print_versions_and_diffs

Expand Down
5 changes: 4 additions & 1 deletion src/ssvc/decision_points/cvss/integrity_requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
# U.S. Patent and Trademark Office by Carnegie Mellon University

from ssvc.decision_points.base import SsvcDecisionPointValue
from ssvc.decision_points.cvss._not_defined import NOT_DEFINED_ND, NOT_DEFINED_X
from ssvc.decision_points.cvss._not_defined import (
NOT_DEFINED_ND,
NOT_DEFINED_X,
)
from ssvc.decision_points.cvss.base import CvssDecisionPoint
from ssvc.decision_points.helpers import print_versions_and_diffs

Expand Down
5 changes: 4 additions & 1 deletion src/ssvc/decision_points/cvss/report_confidence.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
# U.S. Patent and Trademark Office by Carnegie Mellon University

from ssvc.decision_points.base import SsvcDecisionPointValue
from ssvc.decision_points.cvss._not_defined import NOT_DEFINED_ND, NOT_DEFINED_X
from ssvc.decision_points.cvss._not_defined import (
NOT_DEFINED_ND,
NOT_DEFINED_X,
)
from ssvc.decision_points.cvss.base import CvssDecisionPoint
from ssvc.decision_points.helpers import print_versions_and_diffs

Expand Down
22 changes: 17 additions & 5 deletions src/ssvc/decision_points/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ def dp_diff(dp1: SsvcDecisionPoint, dp2: SsvcDecisionPoint) -> list[str]:
major = True

for name in dp2_names.difference(dp1_names):
diffs.append(f"(major or minor) {dp2.name} v{dp2.version} adds value {name}")
diffs.append(
f"(major or minor) {dp2.name} v{dp2.version} adds value {name}"
)
maybe_major = True
maybe_minor = True

Expand All @@ -139,17 +141,27 @@ def dp_diff(dp1: SsvcDecisionPoint, dp2: SsvcDecisionPoint) -> list[str]:
v2 = v2[name]

if v1 != v2:
diffs.append(f"(minor) {dp2.name} v{dp2.version} value {name} key changed")
diffs.append(
f"(minor) {dp2.name} v{dp2.version} value {name} key changed"
)
minor = True
else:
diffs.append(f"{dp2.name} v{dp2.version} value {name} key did not change")
diffs.append(
f"{dp2.name} v{dp2.version} value {name} key did not change"
)

# did the value descriptions change?
for name in intersection:
v1 = {value["name"]: value["description"] for value in dp1.to_dict()["values"]}
v1 = {
value["name"]: value["description"]
for value in dp1.to_dict()["values"]
}
v1 = v1[name]

v2 = {value["name"]: value["description"] for value in dp2.to_dict()["values"]}
v2 = {
value["name"]: value["description"]
for value in dp2.to_dict()["values"]
}
v2 = v2[name]

if v1 != v2:
Expand Down
6 changes: 5 additions & 1 deletion src/ssvc/decision_points/human_impact.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,11 @@


def main():
versions = (MISSION_AND_WELL_BEING_IMPACT_1, HUMAN_IMPACT_2, HUMAN_IMPACT_2_0_1)
versions = (
MISSION_AND_WELL_BEING_IMPACT_1,
HUMAN_IMPACT_2,
HUMAN_IMPACT_2_0_1,
)

print_versions_and_diffs(versions)

Expand Down
8 changes: 6 additions & 2 deletions src/ssvc/decision_points/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
)

LABORIOUS_2 = SsvcDecisionPointValue(
name="Laborious", key="L", description="Automatable:No AND Value Density:Diffuse"
name="Laborious",
key="L",
description="Automatable:No AND Value Density:Diffuse",
)

SUPER_EFFECTIVE = SsvcDecisionPointValue(
Expand All @@ -44,7 +46,9 @@
)

LABORIOUS = SsvcDecisionPointValue(
name="Laborious", key="L", description="Virulence:Slow and Value Density:Diffuse"
name="Laborious",
key="L",
description="Virulence:Slow and Value Density:Diffuse",
)

UTILITY_1 = SsvcDecisionPoint(
Expand Down
19 changes: 15 additions & 4 deletions src/ssvc/doctools.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
import logging
import os

from ssvc.decision_points.base import REGISTERED_DECISION_POINTS, SsvcDecisionPoint
from ssvc.decision_points.base import (
REGISTERED_DECISION_POINTS,
SsvcDecisionPoint,
)
from ssvc.dp_groups.ssvc.collections import SSVCv1, SSVCv2, SSVCv2_1 # noqa

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -154,7 +157,9 @@ def dump_decision_point(
"""
# - generate markdown table
# make dp.name safe for use in a filename
basename = _filename_friendly(dp.name) + f"_{_filename_friendly(dp.version)}"
basename = (
_filename_friendly(dp.name) + f"_{_filename_friendly(dp.version)}"
)
# - generate json example
json_file = dump_json(basename, dp, jsondir, overwrite)

Expand All @@ -165,7 +170,11 @@ def dump_decision_point(


def dump_markdown(
basename: str, dp: SsvcDecisionPoint, json_file: str, outdir: str, overwrite: bool
basename: str,
dp: SsvcDecisionPoint,
json_file: str,
outdir: str,
overwrite: bool,
) -> dict:
"""
Generate the markdown table file for a decision point.
Expand Down Expand Up @@ -266,7 +275,9 @@ def main():
default=False,
)

parser.add_argument("--outdir", help="output directory", default="./tmp/md_out")
parser.add_argument(
"--outdir", help="output directory", default="./tmp/md_out"
)
parser.add_argument(
"--jsondir", help="json output directory", default="./tmp/json_out"
)
Expand Down
17 changes: 13 additions & 4 deletions src/ssvc/dp_groups/cvss/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
ATTACK_VECTOR_3,
ATTACK_VECTOR_3_0_1,
)
from ssvc.decision_points.cvss.authentication import AUTHENTICATION_1, AUTHENTICATION_2
from ssvc.decision_points.cvss.authentication import (
AUTHENTICATION_1,
AUTHENTICATION_2,
)
from ssvc.decision_points.cvss.availability_impact import (
AVAILABILITY_IMPACT_1,
AVAILABILITY_IMPACT_2,
Expand Down Expand Up @@ -96,10 +99,14 @@
SUBSEQUENT_INTEGRITY_IMPACT_1,
)
from ssvc.decision_points.cvss.supplemental.automatable import AUTOMATABLE_1
from ssvc.decision_points.cvss.supplemental.provider_urgency import PROVIDER_URGENCY_1
from ssvc.decision_points.cvss.supplemental.provider_urgency import (
PROVIDER_URGENCY_1,
)
from ssvc.decision_points.cvss.supplemental.recovery import RECOVERY_1
from ssvc.decision_points.cvss.supplemental.safety import SAFETY_1
from ssvc.decision_points.cvss.supplemental.value_density import VALUE_DENSITY_1
from ssvc.decision_points.cvss.supplemental.value_density import (
VALUE_DENSITY_1,
)
from ssvc.decision_points.cvss.supplemental.vulnerability_response_effort import (
VULNERABILITY_RESPONSE_EFFORT_1,
)
Expand Down Expand Up @@ -327,7 +334,9 @@
name="CVSSv4",
description="All decision points for CVSS v4 (including supplemental metrics)",
version="1.0.0",
decision_points=tuple(_BASE_4 + _THREAT_4 + _ENVIRONMENTAL_4 + _SUPPLEMENTAL_4),
decision_points=tuple(
_BASE_4 + _THREAT_4 + _ENVIRONMENTAL_4 + _SUPPLEMENTAL_4
),
)

CVSSv4_Equivalence_Sets = SsvcDecisionPointGroup(
Expand Down
19 changes: 15 additions & 4 deletions src/ssvc/dp_groups/ssvc/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,29 @@
# U.S. Patent and Trademark Office by Carnegie Mellon University


from ssvc.dp_groups.base import SsvcDecisionPointGroup, get_all_decision_points_from
from ssvc.dp_groups.ssvc.coordinator_publication import COORDINATOR_PUBLICATION_1
from ssvc.dp_groups.base import (
SsvcDecisionPointGroup,
get_all_decision_points_from,
)
from ssvc.dp_groups.ssvc.coordinator_publication import (
COORDINATOR_PUBLICATION_1,
)
from ssvc.dp_groups.ssvc.coordinator_triage import COORDINATOR_TRIAGE_1
from ssvc.dp_groups.ssvc.deployer import DEPLOYER_2, DEPLOYER_3, PATCH_APPLIER_1
from ssvc.dp_groups.ssvc.deployer import (
DEPLOYER_2,
DEPLOYER_3,
PATCH_APPLIER_1,
)
from ssvc.dp_groups.ssvc.supplier import PATCH_DEVELOPER_1, SUPPLIER_2


SSVCv1 = SsvcDecisionPointGroup(
name="SSVCv1",
description="The first version of the SSVC.",
version="1.0.0",
decision_points=get_all_decision_points_from(PATCH_APPLIER_1, PATCH_DEVELOPER_1),
decision_points=get_all_decision_points_from(
PATCH_APPLIER_1, PATCH_DEVELOPER_1
),
)
SSVCv2 = SsvcDecisionPointGroup(
name="SSVCv2",
Expand Down
5 changes: 4 additions & 1 deletion src/ssvc/dp_groups/ssvc/deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
from ssvc.decision_points.automatable import AUTOMATABLE_2
from ssvc.decision_points.exploitation import EXPLOITATION_1
from ssvc.decision_points.human_impact import HUMAN_IMPACT_2
from ssvc.decision_points.mission_impact import MISSION_IMPACT_1, MISSION_IMPACT_2
from ssvc.decision_points.mission_impact import (
MISSION_IMPACT_1,
MISSION_IMPACT_2,
)
from ssvc.decision_points.safety_impact import SAFETY_IMPACT_1
from ssvc.decision_points.system_exposure import (
SYSTEM_EXPOSURE_1,
Expand Down
Loading
Loading