Skip to content

Commit

Permalink
PAPP-34988 on_poll updates
Browse files Browse the repository at this point in the history
  • Loading branch information
grokas-splunk committed Nov 25, 2024
1 parent 2c06542 commit 16de483
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 25 deletions.
4 changes: 2 additions & 2 deletions crowdstrike_get_alerts_details.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

{% block widget_content %} <!-- Main Start Block -->

<!-- File: crowdstrike_get_alerts_details.html
<!-- File: crowdstrike_get_epp_alerts_details.html
Copyright (c) 2019-2024 Splunk Inc.
Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -157,7 +157,7 @@ <h3 class="wf-h3-style">Alert Info</h3>
<td>{{data.device.hostname}}</td>
<td>{{data.device.platform_name}}</td>
<td>{{data.status}}</td>
<td>{{data.max_severity_displayname}}</td>
<td>{{data.severity}}</td>
<td>{{data.device.modified_timestamp}}</td>
<td>{{data.created_timestamp}}</td>
</tr>
Expand Down
2 changes: 1 addition & 1 deletion crowdstrike_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def display_view(provides, all_app_runs, context): # noqa: C901
if provides == "get detections details":
return "crowdstrike_get_detections_details.html"

if provides == "get alerts details":
if provides == "get epp alerts details":
return "crowdstrike_get_alerts_details.html"

if provides == "create ioa rule group":
Expand Down
29 changes: 15 additions & 14 deletions crowdstrikeoauthapi_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,14 +583,17 @@ def _handle_resolve_detection(self, param):
def _handle_resolve_epp_alerts(self, param):
action_result = self.add_action_result(ActionResult(dict(param)))

alert_id = param[CROWDSTRIKE_JSON_ID]
composite_ids = param[CROWDSTRIKE_JSON_ID]
to_state = param[CROWDSTRIKE_RESOLVE_DETECTION_TO_STATE]

alert_ids = [x.strip() for x in alert_id.split(",")]
alert_ids = list(filter(None, alert_ids))
if to_state not in CROWDSTRIKE_EPP_ALERT_STATUSES:
return action_result.set_status(phantom.APP_ERROR, CROWDSTRIKE_ERROR_INVALID_ACTION_PARAM.format(key="state"))

composite_ids = [x.strip() for x in composite_ids.split(",")]
composite_ids = list(filter(None, composite_ids))

api_data = {
"composite_ids": alert_ids,
"composite_ids": composite_ids,
"action_parameters": [{
"name": "update_status",
"value": to_state
Expand Down Expand Up @@ -1972,15 +1975,15 @@ def _handle_list_epp_alerts(self, param):
if phantom.is_fail(ret_val):
return action_result.get_status()

alert_ids = response.get("resources", [])
composite_ids = response.get("resources", [])

if not alert_ids:
if not composite_ids:
return action_result.set_status(phantom.APP_SUCCESS, "No alerts found")

all_alerts = []

for i in range(0, len(alert_ids), 100):
batch = alert_ids[i:i + 100]
for i in range(0, len(composite_ids), 100):
batch = composite_ids[i:i + 100]
ret_val, response = self._make_rest_call_helper_oauth2(
action_result,
CROWDSTRIKE_GET_ALERT_DETAILS_ENDPOINT,
Expand Down Expand Up @@ -2032,8 +2035,6 @@ def _handle_get_epp_alerts_details(self, param):
if not composite_ids:
return action_result.set_status(phantom.APP_ERROR, CROWDSTRIKE_ERROR_INVALID_ACTION_PARAM.format(key="alert_ids"))

self.save_progress(f"Retrieving details for {composite_ids} alerts")

ret_val, response = self._make_rest_call_helper_oauth2(
action_result,
CROWDSTRIKE_GET_ALERT_DETAILS_ENDPOINT,
Expand Down Expand Up @@ -2118,7 +2119,7 @@ def _handle_update_epp_alerts(self, param):

status = param.get("status")
if status:
if status not in ["new", "in_progress", "closed", "reopened"]:
if status not in CROWDSTRIKE_EPP_ALERT_STATUSES:
return action_result.set_status(phantom.APP_ERROR, CROWDSTRIKE_ERROR_INVALID_ACTION_PARAM.format(key="status"))
data["action_parameters"].append({
"name": "update_status",
Expand Down Expand Up @@ -2150,7 +2151,7 @@ def _handle_update_epp_alerts(self, param):
if add_tags:
tags = [tag.strip() for tag in add_tags.split(",")]
for tag in tags:
if tag: # Skip empty tags
if tag:
data["action_parameters"].append({
"name": "add_tag",
"value": tag
Expand All @@ -2160,7 +2161,7 @@ def _handle_update_epp_alerts(self, param):
if remove_tags:
tags = [tag.strip() for tag in remove_tags.split(",")]
for tag in tags:
if tag: # Skip empty tags
if tag:
data["action_parameters"].append({
"name": "remove_tag",
"value": tag
Expand Down Expand Up @@ -2851,7 +2852,7 @@ def _on_poll(self, param):

# Need to check both event types
event_type = stream_data.get("metadata", {}).get("eventType")
if stream_data and event_type in ["DetectionSummaryEvent", "EppDetectionSummaryEvent"]:
if stream_data and event_type in CROWDSTRIKE_EVENT_TYPES:
self._events.append(stream_data)
counter = 0 # Reset blank lines counter
event_count += 1
Expand Down
1 change: 1 addition & 0 deletions crowdstrikeoauthapi_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@
]
CROWDSTRIKE_API_SUCC_CODES = [200, 202, 204]
CROWDSTRIKE_DETECTION_STATUSES = ["new", "in_progress", "true_positive", "false_positive", "ignored", "closed", "reopened"]
CROWDSTRIKE_EPP_ALERT_STATUSES = ["new", "in_progress", "closed", "reopened"]
CROWDSTRIKE_EVENT_TYPES = ["DetectionSummaryEvent", "EppDetectionSummaryEvent"]

CROWDSTRIKE_IOA_CREATE_RULE_GROUP_ENDPOINT = "/ioarules/entities/rule-groups/v1"
Expand Down
18 changes: 10 additions & 8 deletions manual_readme_content.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
| [get detections details](#action-get-detections-details) | Detections | &check; | &cross; |
| [update detections](#action-update-detections) | Detections | &cross; | &check; |
| [list alerts](#action-list-alerts) | Alerts | &check; | &cross; |
| [list epp alerts](#action-list-epp-alerts) | Alerts | &check; | &cross; |
| [get epp alerts details](#action-get-epp-alerts-details) | Alerts | &check; | &cross; |
| [update epp alerts](#action-update-epp-alerts) | Alerts | &cross; | &check; |
| [resolve epp alerts](#action-resolve-epp-alerts) | Alerts | &cross; | &check; |
| [list sessions](#action-list-sessions) | Real time response(RTR) | &check; | &cross; |
| [run command](#action-run-command) | Real time response(RTR) | &check; | &cross; |
| [run admin command](#action-run-admin-command) | Real time response(admin) | &cross; | &check; |
Expand Down Expand Up @@ -91,9 +95,9 @@ error.
parameters \[Maximum events to get while POLL NOW\] (default 2000 if not specified) and
\[Maximum events to get while scheduled and interval polling\] (default 10,000 if not
specified). For ingestion, the events are fetched after filtering them based on the event
type - **DetectionSummaryEvent** . The app will exit from the polling cycle in the
types - **DetectionSummaryEvent** and **EppDetectionSummaryEvent**. The app will exit from the polling cycle in the
below-mentioned 2 cases whichever is earlier.
- If the total DetectionSummaryEvents fetched equals the value provided in the \[Maximum
- If the total events fetched equals the value provided in the \[Maximum
events to get while POLL NOW\] (for manual polling) or \[Maximum events to get while
scheduled and interval polling\] (for scheduled | interval polling) parameters
- If the total number of continuous blank lines encountered while streaming the data
Expand All @@ -105,17 +109,15 @@ error.
specified seconds\], all events which are of the same type and on the same host will be put
into one container, as long as the time between those two events is less than the interval.
- The \[Maximum allowed continuous blank lines\] asset configuration parameter will be used to
indicate the allowed number of continuous blank lines while fetching
**DetectionSummaryEvents** . For example, of the entire data of the DetectionSummaryEvents,
some of the 'DetectionSummaryEvents' exists after 100 continuous blank lines and if you've
indicate the allowed number of continuous blank lines while fetching events. For example, if some events exist after 100 continuous blank lines and you've
set the \[Maximum allowed continues blank lines\] parameter value to 500, it will keep on
ingesting all the 'DetectionSummaryEvents' until the code gets 500 continuous blank lines
and hence, it will be able to cover the DetectionSummaryEvents successfully even after the
ingesting all events until the code gets 500 continuous blank lines
and hence, it will be able to cover the events successfully even after the
100 blank lines. If you set it to 50, it will break after the 50th blank line is
encountered. Hence, it won't be able to ingest the events which exist after the 100
continuous blank lines because the code considers that after the configured value in the
\[Maximum allowed continuous blank lines\] configuration parameter (here 50), there is no
data available for the 'DetectionSummaryEvents'.
data available.
- Manual Polling
- During manual poll now, the app starts from the first event that it can query up to the
value configured in the configuration parameter \[Maximum events to get while POLL NOW\] and
Expand Down

0 comments on commit 16de483

Please sign in to comment.