Skip to content

Commit 72c51a4

Browse files
cleanup; log fixes
1 parent 779006e commit 72c51a4

File tree

4 files changed

+26
-30
lines changed

4 files changed

+26
-30
lines changed

contentctl/objects/abstract_security_content_objects/detection_abstract.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@ def source(self) -> str:
279279

280280
deployment: Deployment = Field({})
281281

282-
# TODO (cmcginley): @ljstella removing the refs to confidence and impact?
283282
@computed_field
284283
@property
285284
def annotations(self) -> dict[str, Union[List[str], int, str]]:

contentctl/objects/correlation_search.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@
3131
from contentctl.objects.notable_event import NotableEvent
3232

3333

34+
# TODO (cmcginley): disable logging
3435
# Suppress logging by default; enable for local testing
35-
ENABLE_LOGGING = False
36+
ENABLE_LOGGING = True
3637
LOG_LEVEL = logging.DEBUG
3738
LOG_PATH = "correlation_search.log"
3839

@@ -652,15 +653,8 @@ def validate_risk_events(self) -> None:
652653
f"Unexpected error: Detection '{self.detection.name}' has no RBA objects associated"
653654
" with it; cannot validate."
654655
)
655-
risk_object_counts: dict[str, int] = {str(x): 0 for x in self.detection.rba.risk_objects}
656656

657-
# NOTE: we intentionally want this to be an error state and not a failure state, as
658-
# ultimately this validation should be handled during the build process
659-
if len(self.detection.rba.risk_objects) != len(risk_object_counts):
660-
raise ClientError(
661-
f"At least two risk objects in '{self.detection.name}' have the same name; "
662-
"each risk object for a detection should be unique."
663-
)
657+
risk_object_counts: dict[int, int] = {id(x): 0 for x in self.detection.rba.risk_objects}
664658

665659
# Get the risk events; note that we use the cached risk events, expecting they were
666660
# saved by a prior call to risk_event_exists
@@ -681,20 +675,20 @@ def validate_risk_events(self) -> None:
681675
self.logger.debug(
682676
f"Matched risk event (object={event.risk_object}, type={event.risk_object_type}) "
683677
f"to detection's risk object (name={matched_risk_object.field}, "
684-
f"type={matched_risk_object.type.value} using the source field "
678+
f"type={matched_risk_object.type.value}) using the source field "
685679
f"'{event.source_field_name}'"
686680
)
687-
risk_object_counts[str(matched_risk_object)] += 1
681+
risk_object_counts[id(matched_risk_object)] += 1
688682

689683
# Report any risk objects which did not have at least one match to a risk event
690684
for risk_object in self.detection.rba.risk_objects:
691685
self.logger.debug(
692686
f"Matched risk object (name={risk_object.field}, type={risk_object.type.value} "
693-
f"to {risk_object_counts[str(risk_object)]} risk events."
687+
f"to {risk_object_counts[id(risk_object)]} risk events."
694688
)
695-
if risk_object_counts[str(risk_object)] == 0:
689+
if risk_object_counts[id(risk_object)] == 0:
696690
raise ValidationFailed(
697-
f"Risk object (name={risk_object.field}, type={risk_object.type.value} "
691+
f"Risk object (name={risk_object.field}, type={risk_object.type.value}) "
698692
"was not matched to any risk events."
699693
)
700694

@@ -703,26 +697,26 @@ def validate_risk_events(self) -> None:
703697
# relevant risk object, and the total count should match the total number of events
704698
# individual_count: int | None = None
705699
# total_count = 0
706-
# for risk_object_str in risk_object_counts:
700+
# for risk_object_id in risk_object_counts:
707701
# self.logger.debug(
708-
# f"Risk object <{risk_object_str}> match count: {risk_object_counts[risk_object_str]}"
702+
# f"Risk object <{risk_object_id}> match count: {risk_object_counts[risk_object_id]}"
709703
# )
710704

711705
# # Grab the first value encountered if not set yet
712706
# if individual_count is None:
713-
# individual_count = risk_object_counts[risk_object_str]
707+
# individual_count = risk_object_counts[risk_object_id]
714708
# else:
715709
# # Confirm that the count for the current risk object matches the count of the
716710
# # others
717-
# if risk_object_counts[risk_object_str] != individual_count:
711+
# if risk_object_counts[risk_object_id] != individual_count:
718712
# raise ValidationFailed(
719-
# f"Count of risk events matching detection's risk object <\"{risk_object_str}\"> "
720-
# f"({risk_object_counts[risk_object_str]}) does not match the count of those "
713+
# f"Count of risk events matching detection's risk object <\"{risk_object_id}\"> "
714+
# f"({risk_object_counts[risk_object_id]}) does not match the count of those "
721715
# f"matching other risk objects ({individual_count})."
722716
# )
723717

724718
# # Aggregate total count of events matched to risk objects
725-
# total_count += risk_object_counts[risk_object_str]
719+
# total_count += risk_object_counts[risk_object_id]
726720

727721
# # Raise if the the number of events doesn't match the number of those matched to risk
728722
# # objects

contentctl/objects/detection_tags.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
from pydantic import (
55
BaseModel,
66
Field,
7-
NonNegativeInt,
8-
PositiveInt,
97
computed_field,
108
UUID4,
119
HttpUrl,
@@ -34,14 +32,15 @@
3432
from contentctl.objects.atomic import AtomicEnrichment, AtomicTest
3533
from contentctl.objects.annotated_types import MITRE_ATTACK_ID_TYPE, CVE_TYPE
3634

35+
3736
class DetectionTags(BaseModel):
3837
# detection spec
3938

4039
model_config = ConfigDict(validate_default=False, extra='forbid')
4140
analytic_story: list[Story] = Field(...)
4241
asset_type: AssetType = Field(...)
4342
group: list[str] = []
44-
43+
4544
mitre_attack_id: List[MITRE_ATTACK_ID_TYPE] = []
4645
nist: list[NistCategory] = []
4746

@@ -84,7 +83,7 @@ def cis20(self) -> list[Cis18Value]:
8483

8584
# TODO (#268): Validate manual_test has length > 0 if not None
8685
manual_test: Optional[str] = None
87-
86+
8887
# The following validator is temporarily disabled pending further discussions
8988
# @validator('message')
9089
# def validate_message(cls,v,values):
@@ -117,7 +116,6 @@ def cis20(self) -> list[Cis18Value]:
117116
# )
118117
# return v
119118

120-
# TODO (cmcginley): @ljstella removing risk_score and severity from serialization?
121119
@model_serializer
122120
def serialize_model(self):
123121
# Since this field has no parent, there is no need to call super() serialization function

contentctl/objects/risk_event.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def validate_analyticstories(self, detection: Detection) -> None:
137137
if sorted(self.analyticstories) != sorted(detection_analytic_story):
138138
raise ValidationFailed(
139139
f"Analytic stories in risk event ({self.analyticstories}) do not match those"
140-
f" in detection ({detection.tags.analytic_story})."
140+
f" in detection ({[x.name for x in detection.tags.analytic_story]})."
141141
)
142142

143143
# TODO (cmcginley): all of this type checking is a good use case (potentially) for subtyping
@@ -160,6 +160,9 @@ def validate_risk_message(self, detection: Detection) -> None:
160160
field_replacement_pattern = re.compile(r"\$\S+\$")
161161
tokens = field_replacement_pattern.findall(detection.rba.message)
162162

163+
# TODO (cmcginley): could expand this to get the field values from the raw events and check
164+
# to see that allexpected strings ARE in the risk message (as opposed to checking only
165+
# that unexpected strings aren't)
163166
# Check for the presence of each token in the message from the risk event
164167
for token in tokens:
165168
if token in self.risk_message:
@@ -249,10 +252,12 @@ def get_matched_risk_object(self, risk_objects: set[RiskObject]) -> RiskObject:
249252

250253
# Try to match the risk_object against a specific risk object
251254
if self.source_field_name == risk_object.field:
255+
# TODO (cmcginley): this should be enforced as part of build validation
252256
if matched_risk_object is not None:
253257
raise ValueError(
254-
"Unexpected conditon: we don't expect the source event field "
255-
"corresponding to an risk object's field name to be repeated."
258+
"Unexpected conditon: we don't expect multiple risk objects to use the "
259+
"same field name, so we should not be able match the risk event to "
260+
"multiple risk objects."
256261
)
257262

258263
# TODO (cmcginley): risk objects and threat objects are now in separate sets,

0 commit comments

Comments
 (0)