Skip to content

Commit f72c796

Browse files
resolving some todos
1 parent 72c51a4 commit f72c796

File tree

3 files changed

+17
-28
lines changed

3 files changed

+17
-28
lines changed

contentctl/objects/correlation_search.py

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

3333

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

@@ -665,15 +664,15 @@ def validate_risk_events(self) -> None:
665664
for event in events:
666665
c += 1
667666
self.logger.debug(
668-
f"Validating risk event ({event.risk_object}, {event.risk_object_type}): "
667+
f"Validating risk event ({event.es_risk_object}, {event.es_risk_object_type}): "
669668
f"{c}/{len(events)}"
670669
)
671670
event.validate_against_detection(self.detection)
672671

673672
# Update risk object count based on match
674673
matched_risk_object = event.get_matched_risk_object(self.detection.rba.risk_objects)
675674
self.logger.debug(
676-
f"Matched risk event (object={event.risk_object}, type={event.risk_object_type}) "
675+
f"Matched risk event (object={event.es_risk_object}, type={event.es_risk_object_type}) "
677676
f"to detection's risk object (name={matched_risk_object.field}, "
678677
f"type={matched_risk_object.type.value}) using the source field "
679678
f"'{event.source_field_name}'"

contentctl/objects/rba.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ class ThreatObjectType(str, Enum):
4040
TLS_HASH = "tls_hash"
4141
URL = "url"
4242

43-
# TODO (cmcginley): class names should be capitalized
4443
class risk_object(BaseModel):
4544
field: str
4645
type: RiskObjectType

contentctl/objects/risk_event.py

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@
77
from contentctl.objects.rba import risk_object as RiskObject
88

99

10-
# TODO (cmcginley): the names below now collide a bit with Lou's new class names
1110
class RiskEvent(BaseModel):
1211
"""Model for risk event in ES"""
1312

1413
# The search name (e.g. "ESCU - Windows Modify Registry EnableLinkedConnections - Rule")
1514
search_name: str
1615

1716
# The subject of the risk event (e.g. a username, process name, system name, account ID, etc.)
18-
risk_object: int | str
17+
# (not to be confused w/ the risk object from the detection)
18+
es_risk_object: int | str
1919

20-
# The type of the risk object (e.g. user, system, or other)
21-
risk_object_type: str
20+
# The type of the risk object from ES (e.g. user, system, or other) (not to be confused w/
21+
# the risk object from the detection)
22+
es_risk_object_type: str
2223

2324
# The level of risk associated w/ the risk event
2425
risk_score: int
@@ -140,9 +141,6 @@ def validate_analyticstories(self, detection: Detection) -> None:
140141
f" in detection ({[x.name for x in detection.tags.analytic_story]})."
141142
)
142143

143-
# TODO (cmcginley): all of this type checking is a good use case (potentially) for subtyping
144-
# detections by detection type, instead of having types as enums; could have an EBD subtype
145-
# for any detections that should produce risk so that rba is never None
146144
def validate_risk_message(self, detection: Detection) -> None:
147145
"""
148146
Given the associated detection, validate the risk event's message
@@ -160,7 +158,7 @@ def validate_risk_message(self, detection: Detection) -> None:
160158
field_replacement_pattern = re.compile(r"\$\S+\$")
161159
tokens = field_replacement_pattern.findall(detection.rba.message)
162160

163-
# TODO (cmcginley): could expand this to get the field values from the raw events and check
161+
# TODO (#346): could expand this to get the field values from the raw events and check
164162
# to see that allexpected strings ARE in the risk message (as opposed to checking only
165163
# that unexpected strings aren't)
166164
# Check for the presence of each token in the message from the risk event
@@ -210,12 +208,12 @@ def validate_risk_against_risk_objects(self, risk_objects: set[RiskObject]) -> N
210208

211209
# The risk object type from the risk event should match our mapping of internal risk object
212210
# types
213-
if self.risk_object_type != matched_risk_object.type.value:
211+
if self.es_risk_object_type != matched_risk_object.type.value:
214212
raise ValidationFailed(
215-
f"The risk object type from the risk event ({self.risk_object_type}) does not match"
213+
f"The risk object type from the risk event ({self.es_risk_object_type}) does not match"
216214
" the expected type based on the matched risk object "
217-
f"({matched_risk_object.type.value}): risk event=(object={self.risk_object}, "
218-
f"type={self.risk_object_type}, source_field_name={self.source_field_name}), "
215+
f"({matched_risk_object.type.value}): risk event=(object={self.es_risk_object}, "
216+
f"type={self.es_risk_object_type}, source_field_name={self.source_field_name}), "
219217
f"risk object=(name={matched_risk_object.field}, "
220218
f"type={matched_risk_object.type.value})"
221219
)
@@ -252,30 +250,23 @@ def get_matched_risk_object(self, risk_objects: set[RiskObject]) -> RiskObject:
252250

253251
# Try to match the risk_object against a specific risk object
254252
if self.source_field_name == risk_object.field:
255-
# TODO (cmcginley): this should be enforced as part of build validation
253+
# TODO (#347): enforce that field names are not repeated across risk objects as
254+
# part of build/validate
256255
if matched_risk_object is not None:
257256
raise ValueError(
258257
"Unexpected conditon: we don't expect multiple risk objects to use the "
259258
"same field name, so we should not be able match the risk event to "
260259
"multiple risk objects."
261260
)
262261

263-
# TODO (cmcginley): risk objects and threat objects are now in separate sets,
264-
# so I think we can safely eliminate this check entirely?
265-
# # Report any risk events we find that shouldn't be there
266-
# if RiskEvent.ignore_observable(observable):
267-
# raise ValidationFailed(
268-
# "Risk event matched an observable with an invalid role: "
269-
# f"(name={observable.name}, type={observable.type}, role={observable.role})")
270-
271262
# NOTE: we explicitly do not break early as we want to check each risk object
272263
matched_risk_object = risk_object
273264

274265
# Ensure we were able to match the risk event to a specific risk object
275266
if matched_risk_object is None:
276267
raise ValidationFailed(
277-
f"Unable to match risk event (object={self.risk_object}, type="
278-
f"{self.risk_object_type}, source_field_name={self.source_field_name}) to a "
268+
f"Unable to match risk event (object={self.es_risk_object}, type="
269+
f"{self.es_risk_object_type}, source_field_name={self.source_field_name}) to a "
279270
"risk object in the detection; please check for errors in the risk object types for this "
280271
"detection, as well as the risk event build process in contentctl (e.g. threat "
281272
"objects aren't being converted to risk objects somehow)."

0 commit comments

Comments
 (0)