From 56c4ccd33713b42fde75104d3423343a84a379bd Mon Sep 17 00:00:00 2001 From: Md Azam Date: Mon, 10 Apr 2023 16:20:40 -0300 Subject: [PATCH] Fix: Graph API fails if used without lamda operators on collection type properties (#1421) --- .../stix_translation/query_constructor.py | 19 ++++++++++++++++++- .../test_azure_sentinel_stix_to_query.py | 14 ++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/stix_shifter_modules/azure_sentinel/stix_translation/query_constructor.py b/stix_shifter_modules/azure_sentinel/stix_translation/query_constructor.py index 097ad3f34..947514b60 100644 --- a/stix_shifter_modules/azure_sentinel/stix_translation/query_constructor.py +++ b/stix_shifter_modules/azure_sentinel/stix_translation/query_constructor.py @@ -6,7 +6,13 @@ import re START_STOP_PATTERN = r"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z)" - +# List of Alert properties of type collection without nested properties +ALERT_COLLECTION = ['comments', + 'detectionIds', + 'incidentIds', + 'recommendedActions', + 'sourceMaterials', + 'tags'] class QueryStringPatternTranslator: COUNTER = 0 @@ -193,6 +199,17 @@ def format_comparision_string(comparison_string, mapped_field, lambda_func): .format(collection_name=collection_name, fn=lambda_func, attribute_expression=attribute_expression, comparator=comparator, value=value) + # this condition construct query string for string collection that doesn't contain any nested properties + elif mapped_field in ALERT_COLLECTION: + if comparator == 'ne': + # To negate the result of the expression use the not operator, not the ne operator. + comparison_string += "NOT({collection_name}/any({fn}:{fn} eq {value}))".format( + collection_name=mapped_field, fn=lambda_func, comparator=comparator, + value=value) + else: + comparison_string += "{collection_name}/any({fn}:{fn} {comparator} {value})".format( + collection_name=mapped_field, fn=lambda_func, comparator=comparator, + value=value) else: # check for mapped field that does not have '.' character -> example [azureTenantId,title] if comparator == 'contains': diff --git a/stix_shifter_modules/azure_sentinel/tests/stix_translation/test_azure_sentinel_stix_to_query.py b/stix_shifter_modules/azure_sentinel/tests/stix_translation/test_azure_sentinel_stix_to_query.py index d5564bfaa..62e5ab006 100644 --- a/stix_shifter_modules/azure_sentinel/tests/stix_translation/test_azure_sentinel_stix_to_query.py +++ b/stix_shifter_modules/azure_sentinel/tests/stix_translation/test_azure_sentinel_stix_to_query.py @@ -258,8 +258,6 @@ def test_x_ibm_finding(self): query = translation.translate('azure_sentinel', 'query', '{}', stix_pattern) query['queries'] = _remove_timestamp_from_query(query['queries']) - print(query['queries']) - queries = ["(tolower(title) eq 'photos') and (eventDateTime ge 2021-10-08T00:18:50.449Z and eventDateTime le " "2021-10-08T00:23:50.449Z)", "(tolower(category) eq 'test type') and (eventDateTime ge 2021-10-08T00:18:50.449Z and " @@ -274,3 +272,15 @@ def test_x_ibm_finding(self): "ge 2021-10-08T00:18:50.449Z and eventDateTime le 2021-10-08T00:23:50.449Z)"] queries = _remove_timestamp_from_query(queries) self._test_query_assertions(query, queries) + + def test_lamda_operator_with_collection(self): + stix_pattern = "[x-msazure-sentinel-alert:recommendedActions = 'Enforce' OR x-msazure-sentinel-alert:detectionIds != '111']" + query = translation.translate('azure_sentinel', 'query', '{}', stix_pattern) + query['queries'] = _remove_timestamp_from_query(query['queries']) + + queries = ["(NOT(detectionIds/any(query1:query1 eq '111')) or " + "recommendedActions/any(query2:query2 eq 'Enforce')) and " + "(eventDateTime ge 2023-04-06T15:28:36.645Z and eventDateTime le 2023-04-06T15:33:36.645Z)"] + + queries = _remove_timestamp_from_query(queries) + self._test_query_assertions(query, queries)