From cd34fba676f0305a04dbc9ad928f1c1d8d89d6f0 Mon Sep 17 00:00:00 2001 From: Achintya Jai <153343775+pUrGe12@users.noreply.github.com> Date: Wed, 25 Jun 2025 19:36:50 +0530 Subject: [PATCH] fixing the global flags issue in joomla_template_scan and drupal_theme_scan (#1091) * fixing the global flags issue in joomla template and drupal theme scans, and adding a regex validation testcase * ruff fixes --- nettacker/modules/scan/drupal_theme.yaml | 2 +- nettacker/modules/scan/joomla_template.yaml | 2 +- tests/test_yaml_regexes.py | 87 +++++++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 tests/test_yaml_regexes.py diff --git a/nettacker/modules/scan/drupal_theme.yaml b/nettacker/modules/scan/drupal_theme.yaml index 347ec8ff..ccfb8c24 100644 --- a/nettacker/modules/scan/drupal_theme.yaml +++ b/nettacker/modules/scan/drupal_theme.yaml @@ -37,5 +37,5 @@ payloads: condition_type: or conditions: content: - regex: \/(?i)\bthemes\b\/(.+?)\/ + regex: (?i)\/\bthemes\b\/(.+?)\/ reverse: false diff --git a/nettacker/modules/scan/joomla_template.yaml b/nettacker/modules/scan/joomla_template.yaml index 94dabf72..8715cc27 100644 --- a/nettacker/modules/scan/joomla_template.yaml +++ b/nettacker/modules/scan/joomla_template.yaml @@ -40,5 +40,5 @@ payloads: condition_type: or conditions: content: - regex: \/(?i)\badministrator\/templates\b\/(.+?)\/|\/(?i)templates\/(.+?)\/ + regex: (?i)\/\badministrator\/templates\b\/(.+?)\/|\/templates\/(.+?)\/ reverse: false diff --git a/tests/test_yaml_regexes.py b/tests/test_yaml_regexes.py new file mode 100644 index 00000000..8627aca6 --- /dev/null +++ b/tests/test_yaml_regexes.py @@ -0,0 +1,87 @@ +import os +import re + +import pytest +import yaml + +BASE_DIRS = ["nettacker/modules/vuln", "nettacker/modules/scan"] +DUMMY_TEST_STRING = ( + "This is a random string for testing regex 220-You are user number HTTP/1.1 200 OK" +) + + +def get_yaml_files(): + for base in BASE_DIRS: + for file in os.listdir(base): + if file.endswith(".yaml"): + yield os.path.join(base, file) + + +def load_yaml(file_path): + with open(file_path, "r") as f: + return yaml.safe_load(f) + + +def extract_http_regexes(payloads): + regexes = [] + for payload in payloads: + if payload.get("library") != "http": + continue + for step in payload.get("steps", []): + conditions = step.get("response", {}).get("conditions", {}) + if "content" in conditions and "regex" in conditions["content"]: + regexes.append(conditions["content"]["regex"]) + return regexes + + +def extract_socket_regexes(file_name, payloads): + regexes = [] + + for payload in payloads: + if payload.get("library") != "socket": + continue + for step in payload.get("steps", []): + conditions = step.get("response", {}).get("conditions", {}) + + if "service" in conditions: # for port.yaml + services = conditions["service"] + for service_block in services.values(): + if isinstance(service_block, dict) and "regex" in service_block: + regexes.append(service_block["regex"]) + + elif "time_response" in conditions: # for icmp.yaml + tr = conditions["time_response"] + if isinstance(tr, dict) and "regex" in tr: + regexes.append(tr["regex"]) + + return regexes + + +def is_valid_regex(regex: str) -> bool: + try: + pattern = re.compile(regex) + re.findall(pattern, DUMMY_TEST_STRING) + return True + except Exception: + return False + + +@pytest.mark.parametrize("yaml_file", list(get_yaml_files())) +def test_yaml_regexes_valid(yaml_file): + data = load_yaml(yaml_file) + payloads = data.get("payloads", []) + + if not payloads: + pytest.skip(f"No payloads found in {yaml_file}") + + if payloads[0].get("library") == "http": + regexes = extract_http_regexes(payloads) + elif payloads[0].get("library") == "socket": + file_name = os.path.basename(yaml_file) + regexes = extract_socket_regexes(file_name, payloads) + else: + pytest.skip(f"Unknown library type in {yaml_file}") + return + + for regex in regexes: + assert is_valid_regex(regex), f"Invalid regex in {yaml_file}: `{regex}`"