[Bug] [DaC] Metadata maturity field default mismatch and poor enforcement of rule naming conventions (#4285)

* Add stub for solution

* Add date and maturity logic

* Add date and maturity logic

* Version Bump

* Remove Date Inheritance

* Remove Datetime import
This commit is contained in:
Eric Forte
2025-01-17 12:16:32 -05:00
committed by GitHub
parent f029e9a171
commit 2ea674ce84
3 changed files with 40 additions and 7 deletions
+24 -2
View File
@@ -22,7 +22,7 @@ from .rule_loader import (DEFAULT_PREBUILT_BBR_DIRS,
DEFAULT_PREBUILT_RULES_DIRS, RuleCollection,
dict_filter)
from .schemas import definitions
from .utils import clear_caches
from .utils import clear_caches, rulename_to_filename
def single_collection(f):
@@ -95,6 +95,16 @@ def multi_collection(f):
if len(rules) == 0:
client_error("No rules found")
# Warn that if the path does not match the expected path, it will be saved to the expected path
for rule in rules:
threat = rule.contents.data.get("threat")
first_tactic = threat[0].tactic.name if threat else ""
rule_name = rulename_to_filename(rule.contents.data.name, tactic_name=first_tactic)
if rule.path.name != rule_name:
click.secho(
f"WARNING: Rule path does not match required path: {rule.path.name} != {rule_name}", fg="yellow"
)
kwargs["rules"] = rules
return f(*args, **kwargs)
@@ -200,7 +210,19 @@ def rule_prompt(path=None, rule_type=None, required_only=True, save=True, verbos
# DEFAULT_PREBUILT_RULES_DIRS[0] is a required directory just as a suggestion
suggested_path = Path(DEFAULT_PREBUILT_RULES_DIRS[0]) / contents['name']
path = Path(path or input(f'File path for rule [{suggested_path}]: ') or suggested_path).resolve()
meta = {'creation_date': creation_date, 'updated_date': creation_date, 'maturity': 'development'}
# Inherit maturity from the rule already exists
maturity = "development"
if path.exists():
rules = RuleCollection()
rules.load_file(path)
if rules:
maturity = rules.rules[0].contents.metadata.maturity
meta = {
"creation_date": creation_date,
"updated_date": creation_date,
"maturity": maturity,
}
try:
rule = TOMLRule(path=Path(path), contents=TOMLRuleContents.from_dict({'rule': contents, 'metadata': meta}))
+15 -4
View File
@@ -237,10 +237,21 @@ def kibana_export_rules(ctx: click.Context, directory: Path, action_connectors_d
rule_resource["author"] = rule_resource.get("author") or default_author or [rule_resource.get("created_by")]
if isinstance(rule_resource["author"], str):
rule_resource["author"] = [rule_resource["author"]]
contents = TOMLRuleContents.from_rule_resource(rule_resource, maturity="production")
threat = contents.data.get("threat")
first_tactic = threat[0].tactic.name if threat else ""
rule_name = rulename_to_filename(contents.data.name, tactic_name=first_tactic)
# Inherit maturity from the rule already exists
maturity = "development"
threat = rule_resource.get("threat")
first_tactic = threat[0].get("tactic").get("name") if threat else ""
rule_name = rulename_to_filename(rule_resource.get("name"), tactic_name=first_tactic)
# check if directory / f"{rule_name}" exists
if (directory / f"{rule_name}").exists():
rules = RuleCollection()
rules.load_file(directory / f"{rule_name}")
if rules:
maturity = rules.rules[0].contents.metadata.maturity
contents = TOMLRuleContents.from_rule_resource(
rule_resource, maturity=maturity
)
rule = TOMLRule(contents=contents, path=directory / f"{rule_name}")
except Exception as e:
if skip_errors:
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "detection_rules"
version = "0.3.19"
version = "0.4.0"
description = "Detection Rules is the home for rules used by Elastic Security. This repository is used for the development, maintenance, testing, validation, and release of rules for Elastic Securitys Detection Engine."
readme = "README.md"
requires-python = ">=3.12"