Skip to content

Conversation

@rxerium
Copy link

@rxerium rxerium commented Oct 19, 2025

Proposed change

Your PR description goes here.

Type of change

  • New core framework functionality
  • Bugfix (non-breaking change which fixes an issue)
  • Code refactoring without any functionality changes
  • New or existing module/payload change
  • Documentation/localization improvement
  • Test coverage improvement
  • Dependency upgrade
  • Other improvement (best practice, cleanup, optimization, etc)

Checklist

  • I've followed the contributing guidelines
  • I've run make pre-commit, it didn't generate any changes
  • I've run make test, all tests passed locally

Copilot AI review requested due to automatic review settings October 19, 2025 19:00
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 19, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Summary by CodeRabbit

  • New Features
    • Added version detection and DSL-based version matching capabilities to response evaluation.
    • Enabled support for CVE-style version range matching with logical operators and wildcards.
    • Added new vulnerability detection module for CVE-2025-41244 in VMware Aria Operations.

Walkthrough

Adds a DSL-based version matching engine and exposes it via utilities; integrates version DSL checks into HTTP response evaluation; and adds a new vulnerability module for CVE-2025-41244 using the version DSL for detection.

Changes

Cohort / File(s) Summary
Core DSL matcher & utilities
nettacker/core/utils/dsl_matcher.py, nettacker/core/utils/common.py
Adds DSLMatcher with parsing/evaluation of version DSLs (operators, ranges, wildcards, CVE-style logic), version extraction from responses, and exposes dsl_matcher plus wrapper utilities version_matches_dsl and extract_version_from_content.
HTTP response handling
nettacker/core/lib/http.py
Integrates new condition types version_match and version_dsl into response evaluation: extract version from content or headers, evaluate DSL expressions (with optional reverse logic), and populate condition results accordingly.
Vulnerability payload
nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml
New module for VMware Aria Operations CVE-2025-41244 that uses HTTP payloads with fuzzered URLs and evaluates status, content, and version via the new version DSL (e.g., < 8.18.5).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • securestep9

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "DSL Integration" directly corresponds to the main changes in the pull request, which introduce a comprehensive DSL (Domain-Specific Language) matching engine and integrate it into the core HTTP response evaluation module. The title accurately captures the primary objective of adding DSL-based version matching capabilities to the framework. It is concise and specific enough that a teammate reviewing the git history would understand the key change without needing additional context.
Description Check ✅ Passed The pull request description is clearly related to the changeset. It explicitly mentions "Integration of DSL matching" and explains the purpose as being "particularly useful when creating vulnerability scripts expanding the CVE library," which aligns with the additions to http.py, common.py, dsl_matcher.py, and the new vulnerability module aria_operations_cve_2025_41244.yaml. The description conveys meaningful information about both the feature being added and its practical application.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@rxerium
Copy link
Author

rxerium commented Oct 19, 2025

@coderabbitai review

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds DSL (Domain Specific Language) integration for version matching in vulnerability detection, enabling sophisticated version comparisons using operators, ranges, and semantic matching patterns. The implementation provides a new version_dsl condition type for HTTP response evaluation in vulnerability modules.

Key Changes

  • Added a comprehensive DSL matcher engine with support for various version comparison operators (>=, <, ~, ^), range syntax, wildcards, and logical operators
  • Integrated DSL matching into the HTTP library for use in vulnerability detection modules
  • Created a sample vulnerability module demonstrating DSL usage for VMware Aria Operations CVE-2025-41244

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
nettacker/core/utils/dsl_matcher.py New DSL matching engine with comprehensive version comparison capabilities
nettacker/core/utils/common.py Added utility functions for DSL version matching and content extraction
nettacker/core/lib/http.py Integrated DSL version matching into HTTP response condition evaluation
nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml Example vulnerability module using DSL version matching

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 58 to 60
r'(\d+(?:\.\d+){1,}(?:-[\w\.\-]+)?)', # Version with optional prerelease (e.g., "1.2.3-beta1")
r'[Vv]ersion\s+(\d+(?:\.\d+)*(?:-[\w\.\-]+)?)', # "Version 1.2.3-beta"
r'(\d+(?:\.\d+)*(?:-[\w\.\-]+)?)\s*\([^)]*\)', # "1.2.3-rc (Build 123)"
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern on line 58 uses \.\- in the character class, but the hyphen should be escaped or placed at the end. The current placement could be interpreted as a range. Consider changing to [\w.-] or [\w\.-].

Suggested change
r'(\d+(?:\.\d+){1,}(?:-[\w\.\-]+)?)', # Version with optional prerelease (e.g., "1.2.3-beta1")
r'[Vv]ersion\s+(\d+(?:\.\d+)*(?:-[\w\.\-]+)?)', # "Version 1.2.3-beta"
r'(\d+(?:\.\d+)*(?:-[\w\.\-]+)?)\s*\([^)]*\)', # "1.2.3-rc (Build 123)"
r'(\d+(?:\.\d+){1,}(?:-[\w.-]+)?)', # Version with optional prerelease (e.g., "1.2.3-beta1")
r'[Vv]ersion\s+(\d+(?:\.\d+)*(?:-[\w.-]+)?)', # "Version 1.2.3-beta"
r'(\d+(?:\.\d+)*(?:-[\w.-]+)?)\s*\([^)]*\)', # "1.2.3-rc (Build 123)"

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +96
if check:
parts = [part.strip() for part in re.split(rf'\s*(?:{re.escape(splitter)})\s*', normalized, flags=re.IGNORECASE) if part.strip()]
return combiner(self._evaluate_dsl(part, target_version) for part in parts)
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex compilation in re.split() happens on every evaluation. Consider precompiling these patterns or using a more efficient splitting approach for better performance in high-frequency operations.

Copilot uses AI. Check for mistakes.

return False

def extract_version_from_response(self, content, patterns):
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method extract_version_from_response lacks a docstring explaining its parameters, return value, and usage. This is a public method that would benefit from proper documentation.

Suggested change
def extract_version_from_response(self, content, patterns):
def extract_version_from_response(self, content, patterns):
"""
Extracts a version string from the given content using a list of regex patterns.
Args:
content (str): The text content (e.g., HTTP response) to search for a version string.
patterns (list): A list of regex patterns to match version strings in the content.
Returns:
str or None: The extracted version string if a pattern matches, otherwise None.
Usage:
Use this method to extract version information from service responses or banners.
"""

Copilot uses AI. Check for mistakes.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
nettacker/core/utils/dsl_matcher.py (2)

1-19: Remove unused import.

The SpecifierSet import at line 11 is not used anywhere in the code.

Apply this diff:

 from packaging import version
-from packaging.specifiers import SpecifierSet
 from packaging.version import Version, InvalidVersion

435-449: Consider logging extraction failures for debugging.

The method silently continues on exceptions (line 446), which could make debugging pattern issues difficult. While the current behavior is acceptable for production, consider adding debug logging.

             try:
                 match = re.search(pattern, content, re.IGNORECASE)
                 if match:
                     if match.groups():
                         return match.group(1)
                     return match.group(0)
-            except Exception:
+            except Exception as e:
+                self.logger.debug(f"Pattern '{pattern}' failed: {e}")
                 continue

This helps diagnose issues when version extraction fails unexpectedly.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c538fa and 58970c0.

📒 Files selected for processing (4)
  • nettacker/core/lib/http.py (2 hunks)
  • nettacker/core/utils/common.py (2 hunks)
  • nettacker/core/utils/dsl_matcher.py (1 hunks)
  • nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Use 4-space indents in Python code
Limit lines to 99 characters (ruff/ruff-format/isort profile=black)
Module and file names should use lower_snake_case
Function and variable names should use lower_snake_case
Class names should use PascalCase
Constants should use UPPER_SNAKE_CASE
Keep functions small and add type hints where practical

Files:

  • nettacker/core/utils/common.py
  • nettacker/core/lib/http.py
  • nettacker/core/utils/dsl_matcher.py
nettacker/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Add docstrings for public APIs in the nettacker package

Files:

  • nettacker/core/utils/common.py
  • nettacker/core/lib/http.py
  • nettacker/core/utils/dsl_matcher.py
nettacker/core/**

📄 CodeRabbit inference engine (AGENTS.md)

Place core libraries under nettacker/core/

Files:

  • nettacker/core/utils/common.py
  • nettacker/core/lib/http.py
  • nettacker/core/utils/dsl_matcher.py
nettacker/modules/**

📄 CodeRabbit inference engine (AGENTS.md)

Place pluggable modules under nettacker/modules/

Files:

  • nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml
🧬 Code graph analysis (2)
nettacker/core/utils/common.py (1)
nettacker/core/utils/dsl_matcher.py (2)
  • parse_dsl_expression (21-36)
  • extract_version_from_response (435-449)
nettacker/core/lib/http.py (1)
nettacker/core/utils/common.py (2)
  • version_matches_dsl (456-479)
  • extract_version_from_content (482-493)
🪛 Ruff (0.14.0)
nettacker/core/utils/dsl_matcher.py

1-1: Shebang is present but file is not executable

(EXE001)


34-34: Do not catch blind exception: Exception

(BLE001)


126-126: Do not catch blind exception: Exception

(BLE001)


183-183: Do not catch blind exception: Exception

(BLE001)


220-220: Consider moving this statement to an else block

(TRY300)


222-222: Do not catch blind exception: Exception

(BLE001)


256-256: Consider moving this statement to an else block

(TRY300)


258-258: Do not catch blind exception: Exception

(BLE001)


291-291: Do not catch blind exception: Exception

(BLE001)


327-327: Do not catch blind exception: Exception

(BLE001)


342-342: Do not catch blind exception: Exception

(BLE001)


381-381: Do not catch blind exception: Exception

(BLE001)


446-447: try-except-continue detected, consider logging the exception

(S112)


446-446: Do not catch blind exception: Exception

(BLE001)


480-480: Do not catch blind exception: Exception

(BLE001)

🔇 Additional comments (13)
nettacker/core/utils/common.py (2)

16-16: LGTM!

The import statement is clean and follows the module structure correctly.


456-493: Well-documented utility functions with clean delegation.

Both functions provide clear, well-documented wrappers around the DSL matcher functionality. The comprehensive docstrings with examples make the API easy to understand and use.

nettacker/core/lib/http.py (1)

18-19: LGTM!

The imports are properly added to the existing import statement from nettacker.core.utils.common.

nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml (1)

52-55: Potential version format mismatch.

The regex pattern at line 53 expects a 4-segment version (([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)), but the DSL expression at line 55 compares against a 3-segment version (< 8.18.5).

This may work if the DSL matcher normalizes versions correctly, but it could cause confusion. Consider:

  • If you detect 8.18.5.1234, does < 8.18.5 match?
  • The packaging library typically treats 8.18.5.1234 > 8.18.5, which may be the intended behavior

Verify that the DSL matcher handles different version segment counts correctly by checking the implementation in dsl_matcher.py around lines 38-69 (version cleaning) and lines 143-187 (version comparison).

nettacker/core/utils/dsl_matcher.py (9)

21-36: Entry point method looks solid.

The method appropriately validates inputs, delegates to helper methods, and handles errors defensively by returning False. The broad exception handling is acceptable here as this is an external API boundary and failing safely is appropriate for version matching.


38-69: Comprehensive version cleaning logic.

The method handles various version string formats including prereleases, which is excellent for real-world version detection. The pattern ordering from most specific to most general is a good approach.


71-128: Well-structured DSL evaluation with comprehensive operator support.

The method systematically handles different DSL expression types with proper precedence. The logical connector handling (lines 87-96) correctly processes both symbolic (||, &&) and word-based (or, and) operators with case-insensitive matching.


130-187: Robust version comparison with intelligent fallback strategy.

The three-tier approach (packaging → semver → string comparison) ensures maximum compatibility with various version formats. This defensive design handles edge cases gracefully.


189-259: Correct implementation of semantic versioning operators.

Both tilde and caret operators correctly implement npm/semver semantics. The prerelease stripping and version part comparison logic is sound.


261-292: Thoughtful range expression handling.

The requirement for spaces around the hyphen (line 274) is a smart design decision that avoids confusion with prerelease versions like 1.2.3-beta1. The comment clearly documents this behavior.


294-328: Intelligent comma-separated condition logic.

The categorization of conditions and the use of AND logic for strict range operators vs OR logic for semantic operators (lines 298-325) is well-reasoned for vulnerability detection use cases.


486-487: Global instance is appropriate.

The global dsl_matcher instance is well-suited for this stateless utility class, providing convenient access throughout the codebase.


1-487: Solid DSL matching implementation with comprehensive version support.

This is a well-designed module that handles version matching robustly. The multi-tier fallback strategy, comprehensive operator support, and defensive error handling make it production-ready. The static analysis warnings about bare exceptions are acceptable here given the defensive nature of version parsing.

Key strengths:

  • Clean separation of concerns with helper methods
  • Multiple fallback strategies (packaging → semver → string)
  • Support for various DSL operators and patterns
  • Thoughtful handling of edge cases (prerelease versions, hyphen ambiguity)

Comment on lines +95 to +122
# DSL version matching support
if condition == "version_match":
version_config = conditions[condition]
# Extract version from response using patterns
version_patterns = version_config.get("patterns", [])
source = version_config.get("source", "content")
dsl_expression = version_config.get("expression", "")

# Get the content to search from
search_content = ""
if source == "content":
search_content = response.get("content", "")
elif source == "headers":
header_name = version_config.get("header", "server")
search_content = response.get("headers", {}).get(header_name.lower(), "")

# Extract version
detected_version = extract_version_from_content(search_content, version_patterns)

# Match against DSL expression
if detected_version and dsl_expression:
match_result = version_matches_dsl(detected_version, dsl_expression)
if match_result:
condition_results["version_match"] = [detected_version]
else:
condition_results["version_match"] = []
else:
condition_results["version_match"] = []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Review the config structure documentation.

The implementation assumes a specific structure for version_config with keys like "patterns", "source", "expression", and "header". However, the YAML file uses "expressions" (plural) at line 54, not "expression" (singular) at line 101.

At line 101, the code reads:

dsl_expression = version_config.get("expression", "")

But the YAML at line 54-55 uses:

expressions:
  - "< 8.18.5"

This mismatch means dsl_expression will always be an empty string. You need to decide on singular vs plural and handle accordingly:

-            dsl_expression = version_config.get("expression", "")
+            # Handle both single expression and list of expressions
+            expressions = version_config.get("expressions", [])
+            if not expressions:
+                # Fallback for singular
+                single_expr = version_config.get("expression", "")
+                expressions = [single_expr] if single_expr else []
             
             # Get the content to search from
             search_content = ""
@@ -112,11 +117,13 @@
             detected_version = extract_version_from_content(search_content, version_patterns)
             
             # Match against DSL expression
-            if detected_version and dsl_expression:
-                match_result = version_matches_dsl(detected_version, dsl_expression)
-                if match_result:
-                    condition_results["version_match"] = [detected_version]
-                else:
+            if detected_version and expressions:
+                # Check if version matches ANY expression (OR logic)
+                matched = any(version_matches_dsl(detected_version, expr) for expr in expressions)
+                if matched:
+                    condition_results["version_match"] = [detected_version]
+                else:
                     condition_results["version_match"] = []
             else:
                 condition_results["version_match"] = []
🤖 Prompt for AI Agents
In nettacker/core/lib/http.py around lines 95 to 122, the code reads
version_config.get("expression", "") but the YAML uses "expressions" (plural),
so dsl_expression is always empty; update the code to read the correct key
(decide on singular or plural to match project config) — either change to use
"expressions" and treat it as a list (e.g., use the first expression or iterate
all and succeed on any match) or normalize both keys by checking for
"expression" then "expressions"; then pass the chosen expression string(s) into
version_matches_dsl and set condition_results["version_match"] accordingly
(non-empty when any expression matches), ensuring header lookup still lowercases
header names when source == "headers".

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Critical: Condition name mismatch between implementation and usage.

The code checks for condition == "version_match" (line 96), but the YAML module at line 51 uses version_dsl as the condition key. This mismatch will cause the version matching feature to fail silently.

Looking at the YAML file nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml at line 51, the condition is named version_dsl, but this code expects version_match. You need to align the naming:

Option 1 (Recommended): Change the Python code to match the YAML:

-        if condition == "version_match":
+        if condition == "version_dsl":

Option 2: Change the YAML to use version_match instead of version_dsl.

Additionally, verify this alignment:


🏁 Script executed:

#!/bin/bash
# Search for all usages of version_dsl and version_match in YAML and Python files
echo "=== Checking for version_dsl usage ==="
rg -n "version_dsl" --type yaml --type py

echo "=== Checking for version_match usage ==="
rg -n "version_match" --type yaml --type py

Length of output: 1345


Based on my verification of the codebase, the critical issue identified in the original review comment is confirmed: there is a definitive condition name mismatch that will cause the version matching feature to fail silently.

Critical: Condition name mismatch — YAML uses version_dsl but Python code expects version_match.

The search results confirm:

  • version_dsl appears only in the YAML file at line 51 of nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml
  • version_match appears in the Python condition handler at line 96 of nettacker/core/lib/http.py, where the code checks if condition == "version_match"
  • When the YAML conditions dictionary is iterated, the key will be "version_dsl", which will never match the string "version_match" in the comparison

This mismatch causes the entire version matching feature to be silently skipped—no error is raised, the condition simply doesn't execute.

Fix: Change the YAML condition key from version_dsl to version_match to align with the Python implementation:

-            version_dsl:
+            version_match:

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In nettacker/core/lib/http.py around lines 95 to 122 there is a condition
handler checking for "version_match" but the YAML uses the key "version_dsl",
causing the branch to never execute; fix by aligning the keys so the YAML
condition key is renamed from "version_dsl" to "version_match" (or alternatively
change the Python check to "version_dsl") across the codebase so the iteration
over conditions will trigger the version extraction and DSL matching logic.

Comment on lines +51 to +56
version_dsl:
patterns:
- '\\?version=([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)'
expressions:
- "< 8.18.5"
reverse: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Multiple inconsistencies with the http.py implementation.

The version_dsl configuration has several issues:

  1. Condition name mismatch: Uses version_dsl but http.py line 96 expects version_match
  2. Key mismatch: Uses expressions (plural) at line 54, but http.py line 101 reads expression (singular)
  3. Unsupported field: The reverse field at line 56 is not handled by the implementation in http.py

Apply these fixes to align with the implementation:

-            version_dsl:
+            version_match:
               patterns:
                 - '\\?version=([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)'
-              expressions:
+              expression:
-                - "< 8.18.5"
-              reverse: false
+                "< 8.18.5"

Note: If you want to support multiple expressions, the http.py implementation needs to be updated accordingly (see my comment on http.py lines 95-122).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
version_dsl:
patterns:
- '\\?version=([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)'
expressions:
- "< 8.18.5"
reverse: false
version_match:
patterns:
- '\\?version=([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)'
expression:
"< 8.18.5"
🤖 Prompt for AI Agents
In nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml around lines
51-56, the keys must match the http.py implementation: rename the top-level
block from "version_dsl" to "version_match", change "expressions" to the
singular "expression" and remove the unsupported "reverse" field; leave the
existing pattern and expression value intact (or if you intend to support
multiple expressions, instead update http.py to accept an array named
"expressions" and handle "reverse" there).

@rxerium
Copy link
Author

rxerium commented Oct 20, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 20, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
nettacker/core/utils/dsl_matcher.py (1)

435-449: Add docstring for public method extract_version_from_response.

Per coding guidelines, public APIs in the nettacker package should have docstrings. This method is exposed via the global dsl_matcher instance and used by http.py.

As per coding guidelines

Apply this diff:

     def extract_version_from_response(self, content, patterns):
+        """
+        Extract version string from content using regex patterns.
+        
+        Args:
+            content (str): Text content (e.g., HTTP response) to search for version.
+            patterns (list): List of regex patterns to match version strings.
+            
+        Returns:
+            str or None: Extracted version string if found, otherwise None.
+        """
         if not content or not patterns:
             return None
nettacker/core/lib/http.py (1)

96-122: Remove or consolidate the redundant version_match handler.

This handler duplicates much of the logic in the version_dsl handler (lines 125-155) but with inconsistent feature support:

  • version_match: supports header source but not multiple expressions or reverse logic
  • version_dsl: supports multiple expressions and reverse but only searches content

Since the YAML module uses version_dsl, this handler appears to be unused. Either:

  1. Remove this handler entirely, OR
  2. Consolidate both handlers into one with full feature support

Apply this diff to consolidate by removing the redundant handler:

-        # DSL version matching support
-        if condition == "version_match":
-            version_config = conditions[condition]
-            # Extract version from response using patterns
-            version_patterns = version_config.get("patterns", [])
-            source = version_config.get("source", "content")
-            dsl_expression = version_config.get("expression", "")
-            
-            # Get the content to search from
-            search_content = ""
-            if source == "content":
-                search_content = response.get("content", "")
-            elif source == "headers":
-                header_name = version_config.get("header", "server")
-                search_content = response.get("headers", {}).get(header_name.lower(), "")
-            
-            # Extract version
-            detected_version = extract_version_from_content(search_content, version_patterns)
-            
-            # Match against DSL expression
-            if detected_version and dsl_expression:
-                match_result = version_matches_dsl(detected_version, dsl_expression)
-                if match_result:
-                    condition_results["version_match"] = [detected_version]
-                else:
-                    condition_results["version_match"] = []
-            else:
-                condition_results["version_match"] = []
-        

Alternatively, if both handlers are intentionally kept, add a comment explaining when to use each one. As per coding guidelines.

🧹 Nitpick comments (4)
nettacker/core/lib/http.py (1)

125-155: Consider adding header source support to match version_match features.

The version_dsl handler currently only searches response content (line 133). The earlier version_match handler supports extracting versions from headers as well (lines 105-109). Consider adding header source support here for feature parity, or document why content-only extraction is intentional.

If header support is desired, apply this diff:

         if condition == "version_dsl":
             version_config = conditions[condition]
             # Extract version from response using patterns
             version_patterns = version_config.get("patterns", [])
             dsl_expressions = version_config.get("expressions", [])
             reverse = version_config.get("reverse", False)
+            source = version_config.get("source", "content")
             
-            # Get the content to search from (default to content)
-            search_content = response.get("content", "")
+            # Get the content to search from
+            search_content = ""
+            if source == "content":
+                search_content = response.get("content", "")
+            elif source == "headers":
+                header_name = version_config.get("header", "server")
+                search_content = response.get("headers", {}).get(header_name.lower(), "")
             
             # Extract version
             detected_version = extract_version_from_content(search_content, version_patterns)
nettacker/core/utils/dsl_matcher.py (3)

345-384: Remove unreachable return statement.

Line 384 has a return False that is unreachable because the try-except block at lines 349-382 always returns within both the try and except branches.

Apply this diff:

                 return result != 0
                 
         except Exception:
             return False
-        
-        return False

451-483: Remove unreachable return statement.

Line 483 has a return False that is unreachable because the try-except block at lines 452-481 always returns within both the try and except branches.

Apply this diff:

                 return result != 0
                 
         except Exception:
             return False
-            
-        return False

86-96: Consider precompiling regex patterns for better performance.

The regex pattern is compiled on every call within the loop (line 95). Since these patterns are static based on the splitter type, consider precompiling them as class-level constants or caching them to improve performance in high-frequency DSL evaluation scenarios.

Example refactor to precompile patterns:

class DSLMatcher:
    # Precompile logical operator patterns
    _LOGICAL_PATTERNS = {
        '||': (re.compile(r'\s*(?:\|\|)\s*'), any),
        ' or ': (re.compile(r'\s+or\s+', re.IGNORECASE), any),
        '&&': (re.compile(r'\s*(?:&&)\s*'), all),
        ' and ': (re.compile(r'\s+and\s+', re.IGNORECASE), all),
    }
    
    def _evaluate_dsl(self, dsl_expression, target_version):
        # ... existing code ...
        
        # Use precompiled patterns
        for splitter, (pattern, combiner) in self._LOGICAL_PATTERNS.items():
            if splitter in ['||', '&&']:
                check = splitter in normalized
            else:
                check = pattern.search(normalized)
            
            if check:
                parts = [part.strip() for part in pattern.split(normalized) if part.strip()]
                return combiner(self._evaluate_dsl(part, target_version) for part in parts)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 58970c0 and 7b1a5ab.

📒 Files selected for processing (3)
  • nettacker/core/lib/http.py (2 hunks)
  • nettacker/core/utils/dsl_matcher.py (1 hunks)
  • nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
nettacker/modules/**

📄 CodeRabbit inference engine (AGENTS.md)

Place pluggable modules under nettacker/modules/

Files:

  • nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Use 4-space indents in Python code
Limit lines to 99 characters (ruff/ruff-format/isort profile=black)
Module and file names should use lower_snake_case
Function and variable names should use lower_snake_case
Class names should use PascalCase
Constants should use UPPER_SNAKE_CASE
Keep functions small and add type hints where practical

Files:

  • nettacker/core/utils/dsl_matcher.py
  • nettacker/core/lib/http.py
nettacker/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Add docstrings for public APIs in the nettacker package

Files:

  • nettacker/core/utils/dsl_matcher.py
  • nettacker/core/lib/http.py
nettacker/core/**

📄 CodeRabbit inference engine (AGENTS.md)

Place core libraries under nettacker/core/

Files:

  • nettacker/core/utils/dsl_matcher.py
  • nettacker/core/lib/http.py
🔇 Additional comments (3)
nettacker/core/lib/http.py (1)

18-19: LGTM: Clean imports added for DSL support.

The new utility imports are well-organized and provide the necessary functions for version extraction and DSL matching.

nettacker/modules/vuln/aria_operations_cve_2025_41244.yaml (2)

1-15: LGTM: Severity and metadata accurately reflect CVE-2025-41244.

The severity rating has been corrected to 7.8 (matching the official CVSSv3 score), and the description accurately reflects the local privilege escalation vulnerability in VMware Aria Operations and VMware Tools.


51-56: LGTM: Version DSL configuration now aligns with http.py implementation.

The version_dsl condition configuration correctly uses:

  • expressions (plural) with a list format - matches line 129 in http.py
  • reverse field - handled by line 130 in http.py
  • The condition name version_dsl - matches the handler at line 125 in http.py

Previous mismatches between YAML and Python implementation have been resolved.

Verify the version constraint accurately reflects the CVE:

@rxerium
Copy link
Author

rxerium commented Oct 20, 2025

I will continue to update this PR; something still isn't quite working.

@securestep9
Copy link
Collaborator

@rxerium can you please review the multiple suggestions left by CodeRabbit and Copilot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants