From 85df6b357588ce189f3692edbe05635596398fc1 Mon Sep 17 00:00:00 2001 From: OMpawar-21 Date: Wed, 22 Apr 2026 19:08:05 +0530 Subject: [PATCH] fix: resolve security vulnerabilities in test report generator --- Scripts/generate_integration_test_report.py | 69 +++++---------------- Scripts/requirements.txt | 4 +- 2 files changed, 18 insertions(+), 55 deletions(-) diff --git a/Scripts/generate_integration_test_report.py b/Scripts/generate_integration_test_report.py index aa06777..1bc5dea 100644 --- a/Scripts/generate_integration_test_report.py +++ b/Scripts/generate_integration_test_report.py @@ -4,15 +4,15 @@ Parses TRX (results) + Cobertura (coverage) + Structured StdOut (HTTP, assertions, context) into a single interactive HTML report. -SECURITY ENHANCEMENTS: +SECURITY FEATURES: - Uses defusedxml for secure XML parsing to prevent XXE attacks -- Robust path traversal prevention for all file operations +- Robust path traversal prevention for all file operations - Input validation and sanitization for all user-provided paths -- Safe handling of external entity resolution in XML processing +- No insecure XML parsing fallbacks (security-first approach) -Dependencies: -- defusedxml (optional but recommended for security) -- Python 3.7+ for optimal security features +Requirements: +- defusedxml>=0.7.1 (REQUIRED for secure XML parsing) +- Python 3.7+ recommended """ import xml.etree.ElementTree as ET @@ -23,44 +23,17 @@ import argparse from datetime import datetime -# Try to import defusedxml for safer XML parsing +# Import defusedxml for secure XML parsing (required dependency) try: import defusedxml.ElementTree as SafeET DEFUSED_XML_AVAILABLE = True -except ImportError: - SafeET = None - DEFUSED_XML_AVAILABLE = False +except ImportError as e: + print("ERROR: defusedxml is required for secure XML parsing.") + print("Install it with: pip install defusedxml") + print("This prevents XXE vulnerabilities in XML processing.") + sys.exit(1) -def _make_xml_parser(): - """ - Create a hardened XML parser that prevents XXE and other XML-based attacks. - Uses defusedxml for safer XML parsing when available. - """ - if DEFUSED_XML_AVAILABLE: - return None # defusedxml uses its own parser - - # Fallback to standard parser with security restrictions - parser = ET.XMLParser() - - # For Python 3.8+, disable resolve_entities - if sys.version_info >= (3, 8): - try: - parser = ET.XMLParser(resolve_entities=False) - except TypeError: - pass - - # Additional hardening for older versions - if hasattr(parser, 'parser'): - try: - # Disable external entity processing - parser.parser.DefaultHandler = lambda data: None - parser.parser.ExternalEntityRefHandler = lambda *args: False - parser.parser.EntityDeclHandler = lambda *args: False - except AttributeError: - pass - - return parser def _sanitize_output_path(output_path): @@ -133,15 +106,9 @@ def __init__(self, trx_path, coverage_path=None): # ──────────────────── TRX PARSING ──────────────────── def parse_trx(self): - # Safely parse TRX file with defusedxml when available + # Safely parse TRX file with defusedxml (required for security) try: - if DEFUSED_XML_AVAILABLE: - tree = SafeET.parse(self.trx_path) - else: - # Warn about potential security risk - print("Warning: defusedxml not available. Using standard XML parser with limited security mitigations.") - parser = _make_xml_parser() - tree = ET.parse(self.trx_path, parser=parser) + tree = SafeET.parse(self.trx_path) root = tree.getroot() except Exception as e: raise ValueError(f"Failed to parse TRX file safely: {e}") from e @@ -259,12 +226,8 @@ def parse_coverage(self): if not self.coverage_path or not os.path.exists(self.coverage_path): return try: - # Safely parse coverage file with defusedxml when available - if DEFUSED_XML_AVAILABLE: - tree = SafeET.parse(self.coverage_path) - else: - parser = _make_xml_parser() - tree = ET.parse(self.coverage_path, parser=parser) + # Safely parse coverage file with defusedxml (required for security) + tree = SafeET.parse(self.coverage_path) root = tree.getroot() self.coverage['lines_pct'] = float(root.get('line-rate', 0)) * 100 self.coverage['branches_pct'] = float(root.get('branch-rate', 0)) * 100 diff --git a/Scripts/requirements.txt b/Scripts/requirements.txt index d0564c7..17c55a7 100644 --- a/Scripts/requirements.txt +++ b/Scripts/requirements.txt @@ -1,3 +1,3 @@ -# Requirements for Scripts directory -# For secure XML parsing in generate_integration_test_report.py +# Required dependencies for Scripts directory +# defusedxml: REQUIRED for secure XML parsing (prevents XXE vulnerabilities) defusedxml>=0.7.1 \ No newline at end of file