RemediationPathRuleEvaluation
For a given alert and remediation path rules that are defined for that alert's attack surface rule, this script takes each remediation path rule and looks at the rule criteria to see if the rule matches for the given alert. If multiple rules match, it will return the most recently created rule. This assumes that the rules passed in are filtered to correlate with the alert's attack surface rule.
python · Cortex Attack Surface Management
Details
| ID | RemediationPathRuleEvaluation |
|---|---|
| Language | python |
| From Version | 6.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
README
For a given alert and remediation path rules that are defined for that alert’s attack surface rule, this script takes each remediation path rule and looks at the rule criteria to see if the rule matches for the given alert. If multiple rules match, it will return the most recently created rule. This assumes that the rules passed in are filtered to correlate with the alert’s attack surface rule.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
Inputs
| Argument Name | Description |
|---|---|
| severity | Alert’s Severity. |
| ip | Alert’s Remote IP. |
| development_environment | Is this in a development environment? |
| cloud_managed | Is this cloud managed? |
| service_owner_identified | Has a service owner been identified? |
| tags | Includes Cloud and Xpanse tags |
| providers | Externally Detected Providers |
| remediation_path_rules | List of remediation path rules for the alert’s attack surface rule. |
Outputs
There are no outputs for this script.
from RemediationPathRuleEvaluation import evaluate_criteria, match_remediation_rule import demistomock as demisto # noqa: F401 import pytest ALERT_CONTEXT = { "severity": 1, "ip": "1.1.1.1", "tag": [ {"key": "env", "source": "AWS", "value": "dev"}, {"key": "Name", "source": "AWS", "value": "rdp_server"}, ], "provider": ["Amazon Web Services", "Google"], "development_environment": True, "cloud_managed": [ { "organization": "n/a", "other": "us-east-1a", "project": "n/a", "provider": "AWS", "region": "us-east-1", } ], "service_owner_identified": [ { "email": "n/a", "name": "service_XSOAR", "source": "AWS", "timestamp": "2023-01-26T15:51:17.346Z", } ], } # Evaluate Criteria Tests # @pytest.mark.parametrize( "test_condition, test_alert_context, expected_result", [ ({"field": "severity", "operator": "eq", "value": "LOW"}, ALERT_CONTEXT, True), ({"field": "severity", "operator": "eq", "value": "HIGH"}, ALERT_CONTEXT, False), ({"field": "severity", "operator": "eq", "value": "MEDIUM"}, {"severity": None}, False), ], ) def test_evaluate_criteria_severity(test_condition, test_alert_context, expected_result): assert evaluate_criteria(test_condition, test_alert_context) is expected_result @pytest.mark.parametrize( "test_condition, test_alert_context, expected_result", [ ({"field": "ip", "operator": "eq", "value": "1.1.1.1"}, ALERT_CONTEXT, True), ({"field": "ip", "operator": "eq", "value": "2.2.2.2"}, ALERT_CONTEXT, False), ({"field": "ip", "operator": "eq", "value": "1.1.1.1"}, {"ip": None}, False), ], ) def test_evaluate_criteria_ip(test_condition, test_alert_context, expected_result): assert evaluate_criteria(test_condition, test_alert_context) is expected_result @pytest.mark.parametrize( "test_condition, test_alert_context, expected_result", [ ({"field": "tag", "operator": "eq", "value": "rdp_server"}, ALERT_CONTEXT, True), ({"field": "tag", "operator": "eq", "value": "env"}, ALERT_CONTEXT, True), ({"field": "tag", "operator": "eq", "value": "wrong"}, ALERT_CONTEXT, False), ], ) def test_evaluate_criteria_tag(test_condition, test_alert_context, expected_result): assert evaluate_criteria(test_condition, test_alert_context) is expected_result @pytest.mark.parametrize( "test_condition, test_alert_context, expected_result", [ ({"field": "provider", "operator": "eq", "value": "amazon web services"}, ALERT_CONTEXT, True), ({"field": "provider", "operator": "eq", "value": "amazon web services"}, {"provider": "Amazon Web Services"}, True), ({"field": "provider", "operator": "eq", "value": "amazon web services"}, {"provider": None}, False), ({"field": "provider", "operator": "eq", "value": "aws"}, ALERT_CONTEXT, False), ], ) def test_evaluate_criteria_provider(test_condition, test_alert_context, expected_result): assert evaluate_criteria(test_condition, test_alert_context) is expected_result test_data = [ ("development_environment", True), ("cloud_managed", False), ("service_owner_identified", False), ] @pytest.mark.parametrize("field_name, is_boolean", test_data) def test_evaluate_criteria_boolean_type_check(field_name, is_boolean): # is_boolean is True if the field can actually be a True/False value vs. # is_boolean is False if True/False is determined by the presence of the field's value # test criteria condition is true cond = {"field": field_name, "operator": "eq", "value": "true"} assert evaluate_criteria(cond, ALERT_CONTEXT) is True if is_boolean: alert_context = {field_name: False} assert evaluate_criteria(cond, alert_context) is False alert_context = {field_name: None} assert evaluate_criteria(cond, alert_context) is False # test criteria condition is false cond = {"field": field_name, "operator": "eq", "value": "false"} assert evaluate_criteria(cond, ALERT_CONTEXT) is False if is_boolean: alert_context = {field_name: False} assert evaluate_criteria(cond, alert_context) is True alert_context = {field_name: None} assert evaluate_criteria(cond, alert_context) is True # Match Remediation Rule Tests # def test_match_remediation_rule_basic(): # multiple rule matches rules = [ { "rule_id": "8e4ff951-9e17-492a-8fd8-c2a0f45b0d36", "rule_name": "RDP dev rule", "description": "add a Rdp rule", "attack_surface_rule_id": "RdpServer", "criteria": [ {"field": "development_environment", "value": "true", "operator": "eq"}, {"field": "ip", "value": "1.1.1.1", "operator": "eq"}, ], "criteria_conjunction": "AND", "action": "email", "created_by": "noc@acme.com", "created_by_pretty": "First Last", "created_at": 1674264241000, }, { "rule_id": "36b215c3-a336-40e3-bf13-0b976c72ebb6", "rule_name": "SSH Severity Rule", "description": "A SshServer Rule", "attack_surface_rule_id": "SshServer", "criteria": [{"field": "severity", "value": "low", "operator": "eq"}], "criteria_conjunction": "AND", "action": "servicenow", "created_by": "noc@acme.com", "created_by_pretty": "First Last", "created_at": 1674540567000, }, ] matched_rule = match_remediation_rule(ALERT_CONTEXT, rules) assert len(matched_rule) == 1 assert matched_rule[0]["rule_id"] == "36b215c3-a336-40e3-bf13-0b976c72ebb6" # multiple criteria matches rules = [ { "rule_id": "8e4ff951-9e17-492a-8fd8-c2a0f45b0d36", "rule_name": "RDP dev rule", "description": "add a Rdp rule", "attack_surface_rule_id": "RdpServer", "criteria": [ {"field": "development_environment", "value": "true", "operator": "eq"}, {"field": "ip", "value": "1.1.1.1", "operator": "eq"}, ], "criteria_conjunction": "AND", "action": "email", "created_by": "noc@acme.com", "created_by_pretty": "First Last", "created_at": 1674264241000, }, { "rule_id": "36b215c3-a336-40e3-bf13-0b976c72ebb6", "rule_name": "SSH Severity Rule", "description": "A SshServer Rule", "attack_surface_rule_id": "SshServer", "criteria": [{"field": "severity", "value": "high", "operator": "eq"}], "criteria_conjunction": "AND", "action": "servicenow", "created_by": "noc@acme.com", "created_by_pretty": "First Last", "created_at": 1674540567000, }, ] matched_rule = match_remediation_rule(ALERT_CONTEXT, rules) assert len(matched_rule) == 1 assert matched_rule[0]["rule_id"] == "8e4ff951-9e17-492a-8fd8-c2a0f45b0d36" # pass in 1 rule rules = { "rule_id": "8e4ff951-9e17-492a-8fd8-c2a0f45b0d36", "rule_name": "RDP dev rule", "description": "add a Rdp rule", "attack_surface_rule_id": "RdpServer", "criteria": [ {"field": "development_environment", "value": "true", "operator": "eq"}, {"field": "ip", "value": "1.1.1.1", "operator": "eq"}, ], "criteria_conjunction": "AND", "action": "email", "created_by": "noc@acme.com", "created_by_pretty": "First Last", "created_at": 1674264241000, } matched_rule = match_remediation_rule(ALERT_CONTEXT, rules) assert len(matched_rule) == 1 assert matched_rule[0]["rule_id"] == "8e4ff951-9e17-492a-8fd8-c2a0f45b0d36" # only one criteria matches - no rule match rules = [ { "rule_id": "8e4ff951-9e17-492a-8fd8-c2a0f45b0d36", "rule_name": "RDP dev rule", "description": "add a Rdp rule", "attack_surface_rule_id": "RdpServer", "criteria": [ {"field": "development_environment", "value": "true", "operator": "eq"}, {"field": "ip", "value": "2.2.2.2", "operator": "eq"}, ], "criteria_conjunction": "AND", "action": "email", "created_by": "noc@acme.com", "created_by_pretty": "First Last", "created_at": 1674264241000, }, { "rule_id": "36b215c3-a336-40e3-bf13-0b976c72ebb6", "rule_name": "SSH Severity Rule", "description": "A SshServer Rule", "attack_surface_rule_id": "SshServer", "criteria": [{"field": "severity", "value": "high", "operator": "eq"}], "criteria_conjunction": "AND", "action": "servicenow", "created_by": "noc@acme.com", "created_by_pretty": "First Last", "created_at": 1674540567000, }, ] matched_rule = match_remediation_rule(ALERT_CONTEXT, rules) assert len(matched_rule) == 0 # empty list of rules rules = [] matched_rule = match_remediation_rule(ALERT_CONTEXT, rules) assert len(matched_rule) == 0