# app/rules/factory.py from pathlib import Path from app.logging_setup import get_engine_logger from app.rules.rules_engine import RuleEngine from app.rules.rules_engine import Rule from app.rules.function_rules import FunctionRuleAdapter from app.rules.function_rules import ( form_action_missing, form_http_on_https_page, form_submits_to_different_host, script_src_uses_data_or_blob, script_src_has_dangerous_extension, script_third_party_host, ) from app.rules.rules_engine import load_rules_from_yaml base_dir = Path(__file__).resolve().parent.parent RULES_FILE_PATH = base_dir / "config" / "suspicious_rules.yaml" log = get_engine_logger() def build_rules_engine() -> RuleEngine: eng = RuleEngine() # 1) YAML rules yaml_rules = load_rules_from_yaml(RULES_FILE_PATH) for r in yaml_rules: eng.add_rule(r) log.info("Found %d suspicious rules from %s", len(yaml_rules), getattr(yaml_rules, "source_path", "config")) # 2) Function rules from app.rules.function_rules import FactAdapter adapter = FactAdapter() def add(rule: Rule): eng.add_rule(rule) # Form no action add(Rule( name="form_action_missing", description="Form has no action attribute", category="form", rule_type="function", function=FunctionRuleAdapter(form_action_missing, category="form", adapter=adapter, rule_name="form_action_missing"), )) # add(Rule( # name="form_http_on_https_page", # description="Form submits via HTTP from HTTPS page", # category="form", # rule_type="function", # function=FunctionRuleAdapter(form_http_on_https_page, category="form", adapter=adapter, rule_name="form_http_on_https_page"), # )) # add(Rule("form_http_on_https_page", "Form submits via HTTP from HTTPS page", "form", "function", # FunctionRuleAdapter(form_http_on_https_page, category="form", adapter=adapter, rule_name="form_http_on_https_page"))) # add(Rule("form_submits_to_different_host", "Form submits to a different host", "form", "function", # FunctionRuleAdapter(form_submits_to_different_host, category="form", adapter=adapter, rule_name="form_submits_to_different_host"))) # add(Rule("script_src_uses_data_or_blob", "Script src uses data:/blob: URL", "script", "function", # FunctionRuleAdapter(script_src_uses_data_or_blob, category="script", adapter=adapter, rule_name="script_src_uses_data_or_blob"))) # add(Rule("script_src_has_dangerous_extension", "External script with dangerous extension", "script", "function", # FunctionRuleAdapter(script_src_has_dangerous_extension, category="script", adapter=adapter, rule_name="script_src_has_dangerous_extension"))) # add(Rule("script_third_party_host", "Script is from a third-party host", "script", "function", # FunctionRuleAdapter(script_third_party_host, category="script", adapter=adapter, rule_name="script_third_party_host"))) log.info("Registered %d total rules (YAML + function)", len(eng.rules)) return eng