From 200fbe939e1fbdc6c167d88c35f98d014e9058bb Mon Sep 17 00:00:00 2001 From: Justin Ibarra Date: Tue, 8 Dec 2020 23:16:59 +0100 Subject: [PATCH] [Bug] Allow duplicative queries across different rule types (#704) --- detection_rules/rule_loader.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/detection_rules/rule_loader.py b/detection_rules/rule_loader.py index 2528d452a..f04fa5c7f 100644 --- a/detection_rules/rule_loader.py +++ b/detection_rules/rule_loader.py @@ -79,6 +79,7 @@ def load_rules(file_lookup=None, verbose=True, error=True): rules = [] # type: list[Rule] errors = [] queries = [] + query_check_index = [] rule_ids = set() rule_names = set() @@ -87,22 +88,28 @@ def load_rules(file_lookup=None, verbose=True, error=True): rule = Rule(rule_file, rule_contents) if rule.id in rule_ids: - raise KeyError("Rule has duplicate ID to {}".format(next(r for r in rules if r.id == rule.id).path)) + existing = next(r for r in rules if r.id == rule.id) + raise KeyError(f'{rule.path} has duplicate ID with \n{existing.path}') if rule.name in rule_names: - raise KeyError("Rule has duplicate name to {}".format( - next(r for r in rules if r.name == rule.name).path)) + existing = next(r for r in rules if r.name == rule.name) + raise KeyError(f'{rule.path} has duplicate name with \n{existing.path}') parsed_query = rule.parsed_query if parsed_query is not None: - if parsed_query in queries: - raise KeyError("Rule has duplicate query with {}".format( - next(r for r in rules if r.parsed_query == parsed_query).path)) + # duplicate logic is ok across query and threshold rules + threshold = rule.contents.get('threshold', {}) + duplicate_key = (parsed_query, rule.type, threshold.get('field'), threshold.get('value')) + query_check_index.append(rule) - queries.append(parsed_query) + if duplicate_key in queries: + existing = query_check_index[queries.index(duplicate_key)] + raise KeyError(f'{rule.path} has duplicate query with \n{existing.path}') + + queries.append(duplicate_key) if not re.match(FILE_PATTERN, os.path.basename(rule.path)): - raise ValueError(f"Rule {rule.path} does not meet rule name standard of {FILE_PATTERN}") + raise ValueError(f'{rule.path} does not meet rule name standard of {FILE_PATTERN}') rules.append(rule) rule_ids.add(rule.id)