[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:
@@ -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}))
|
||||
|
||||
@@ -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
@@ -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 Security’s Detection Engine."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
Reference in New Issue
Block a user