From: Jason Ish Date: Wed, 2 Jul 2025 17:52:27 +0000 (-0600) Subject: rules: fix parsing of address lists X-Git-Tag: 1.3.6~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b7ad6e75ae9d1a5372c9ab950ca822ff359f6c5;p=thirdparty%2Fsuricata-update.git rules: fix parsing of address lists The previous parser just looked for the next "]" to find the end of a list without respect for list depth. Instead step through the array tracking the depth of the nested lists. Ticket: #7799 --- diff --git a/suricata/update/rule.py b/suricata/update/rule.py index 169af6c..20ff868 100644 --- a/suricata/update/rule.py +++ b/suricata/update/rule.py @@ -212,9 +212,16 @@ def parse(buf, group=None): if not rem: return None if rem[0] == "[": - end = rem.find("]") - if end < 0: - return + depth = 1 + end = 0 + while depth > 0: + end += 1 + if end >= len(rem): + return + if rem[end] == "[": + depth += 1 + elif rem[end] == "]": + depth -= 1 end += 1 token = rem[:end].strip() rem = rem[end:].strip() diff --git a/tests/test_rule.py b/tests/test_rule.py index c5808d8..a034117 100644 --- a/tests/test_rule.py +++ b/tests/test_rule.py @@ -254,3 +254,11 @@ alert dnp3 any any -> any any (msg:"SURICATA DNP3 Request flood detected"; \ rule = suricata.update.rule.parse(rule_string) self.assertIsNotNone(rule) self.assertTrue("ja3" in rule["features"]) + + def test_parse_var_lists(self): + rule_string = u"""alert http [any,![$EXTERNAL_IP,$REVERSE_PROXY_HOSTS,$ODD_HTTP_HOSTS]] any -> [any,![$EXTERNAL_IP,$REVERSE_PROXY_HOSTS,$ODD_HTTP_HOSTS]] 80 (msg:"TEST Unknown var"; sid: 99000003; rev: 1;)""" + rule = suricata.update.rule.parse(rule_string) + self.assertEqual(rule["source_addr"], "[any,![$EXTERNAL_IP,$REVERSE_PROXY_HOSTS,$ODD_HTTP_HOSTS]]") + self.assertEqual(rule["source_port"], "any") + self.assertEqual(rule["dest_addr"], "[any,![$EXTERNAL_IP,$REVERSE_PROXY_HOSTS,$ODD_HTTP_HOSTS]]") + self.assertEqual(rule["dest_port"], "80")