# EU-Utility Security Fixes Applied **Date:** 2026-02-14 **Auditor:** Security Auditor Agent --- ## Summary This document details the security fixes applied during the security audit of EU-Utility. **Modules Fixed:** 4 **Security Improvements:** 15+ **Risk Level Reduced:** MEDIUM-HIGH → LOW-MEDIUM --- ## Fixes Applied ### 1. ✅ data_store.py - Path Traversal Protection **Action:** Replaced vulnerable module with secure version **Changes:** - Backup created: `data_store_vulnerable.py` - Active module now: `data_store_secure.py` **Security Features Added:** - Path validation using `PathValidator` class - Resolved path verification against base directory - Plugin ID validation (type checking, empty checks) - Key validation against dangerous patterns - Data structure validation before save - Backup path traversal protection **Code Example:** ```python def _get_plugin_file(self, plugin_id: str) -> Path: # Validate plugin_id if not isinstance(plugin_id, str): raise SecurityError("plugin_id must be a string") # Sanitize and validate safe_name = PathValidator.sanitize_filename(plugin_id, '_') if '..' in safe_name or '/' in safe_name or '\\' in safe_name: raise SecurityError(f"Invalid characters in plugin_id: {plugin_id}") # Verify resolved path is within base directory file_path = self.data_dir / f"{safe_name}.json" resolved_path = file_path.resolve() if not str(resolved_path).startswith(str(self._base_path)): raise SecurityError(f"Path traversal detected: {plugin_id}") return file_path ``` --- ### 2. ✅ screenshot.py - Filename Sanitization & Path Validation **Action:** Replaced vulnerable module with secure version **Changes:** - Backup created: `screenshot_vulnerable.py` - Active module now: `screenshot_secure.py` **Security Features Added:** - Filename sanitization using `PathValidator.sanitize_filename()` - Path resolution validation against base save path - Region coordinate validation (prevent DoS via huge regions) - Window handle validation (type and value checking) - Dimension sanity checks **Code Example:** ```python def save_screenshot(self, image: Image.Image, filename: Optional[str] = None) -> Path: # Sanitize filename safe_filename = PathValidator.sanitize_filename(filename, '_') filepath = self._save_path / safe_filename # Security check: ensure resolved path is within save_path try: resolved_path = filepath.resolve() if not str(resolved_path).startswith(str(self._base_save_path)): raise SecurityError("Path traversal detected in filename") except (OSError, ValueError) as e: # Fallback to safe default safe_filename = f"screenshot_{int(time.time())}.{self._format.lower()}" filepath = self._save_path / safe_filename ``` --- ### 3. ✅ clipboard.py - Input Validation & Size Limits **Action:** Enhanced with security validation **Security Features Added:** - Maximum text length limit (10KB per entry) - Maximum total storage limit (1MB) - Null byte detection and rejection - Text sanitization (control character removal) - Source string length limiting - Secure file permissions (0o600 - owner only) - Temporary file atomic write pattern **Code Example:** ```python def _validate_text(self, text: str) -> tuple[bool, str]: if not isinstance(text, str): return False, "Text must be a string" if '\x00' in text: return False, "Text contains null bytes" if len(text) > self._max_text_length: return False, f"Text exceeds maximum length" # Auto-cleanup to make room current_size = sum(len(entry.text) for entry in self._history) if current_size + len(text) > self._max_total_storage: while self._history and current_size + len(text) > self._max_total_storage: removed = self._history.popleft() current_size -= len(removed.text) return True, "" def _save_history(self): # Write with restricted permissions temp_path = self._history_file.with_suffix('.tmp') with open(temp_path, 'w', encoding='utf-8') as f: json.dump(data, f, indent=2) os.chmod(temp_path, 0o600) # Owner read/write only temp_path.replace(self._history_file) ``` --- ### 4. ✅ http_client.py - URL Validation & SSRF Protection **Action:** Enhanced with security validation **Security Features Added:** - URL scheme validation (only http:// and https:// allowed) - Path traversal pattern detection (`..`, `@`, `\`, null bytes) - SSRF protection (blocks private, loopback, reserved, link-local IPs) - Custom exception classes for security errors - URL validation on both GET and POST requests **Code Example:** ```python def _validate_url(self, url: str) -> str: if not url: raise URLSecurityError("URL cannot be empty") from urllib.parse import urlparse parsed = urlparse(url) # Check scheme allowed_schemes = {'http', 'https'} if parsed.scheme not in allowed_schemes: raise URLSecurityError(f"URL scheme '{parsed.scheme}' not allowed") # Check for dangerous patterns dangerous_patterns = ['..', '@', '\\', '\x00'] for pattern in dangerous_patterns: if pattern in url: raise URLSecurityError(f"URL contains dangerous pattern") # SSRF protection - block private IPs hostname = parsed.hostname if hostname: try: ip = ipaddress.ip_address(hostname) if ip.is_private or ip.is_loopback or ip.is_reserved: raise URLSecurityError(f"URL resolves to restricted IP") except ValueError: pass # Not an IP, it's a hostname return url ``` --- ## Files Modified | File | Action | Status | |------|--------|--------| | `core/data_store.py` | Replaced with secure version | ✅ Fixed | | `core/data_store_vulnerable.py` | Backup created | ✅ Archived | | `core/screenshot.py` | Replaced with secure version | ✅ Fixed | | `core/screenshot_vulnerable.py` | Backup created | ✅ Archived | | `core/clipboard.py` | Enhanced with validation | ✅ Fixed | | `core/http_client.py` | Added URL validation | ✅ Fixed | --- ## Remaining Recommendations ### Medium Priority (Not Yet Implemented) 1. **Plugin Manager Security** - Implement plugin signature verification - Add permission manifest system - Consider sandboxed execution environment 2. **Audit Logging** - Log all security violations - Log plugin loading/unloading - Log file operations outside data directories ### Low Priority (Future Enhancements) 3. **Data Encryption** - Encrypt sensitive plugin data at rest - Encrypt clipboard history with user password 4. **Rate Limiting** - Per-plugin API rate limits - Screenshot capture rate limiting --- ## Testing Security Fixes ### Path Traversal Test ```python from core.data_store import get_data_store data_store = get_data_store() # Should raise SecurityError try: data_store.save("../../../etc/passwd", "key", "data") except SecurityError: print("✅ Path traversal blocked in data_store") # Should raise SecurityError try: from core.screenshot import get_screenshot_service service = get_screenshot_service() service.save_screenshot(image, "../../../malware.exe") except SecurityError: print("✅ Path traversal blocked in screenshot") ``` ### URL Validation Test ```python from core.http_client import HTTPClient, URLSecurityError client = HTTPClient() # Should raise URLSecurityError try: client.get("file:///etc/passwd") except URLSecurityError: print("✅ File protocol blocked") try: client.get("http://127.0.0.1/admin") except URLSecurityError: print("✅ Localhost blocked (SSRF protection)") try: client.get("http://192.168.1.1/admin") except URLSecurityError: print("✅ Private IP blocked (SSRF protection)") ``` ### Clipboard Validation Test ```python from core.clipboard import get_clipboard_manager clipboard = get_clipboard_manager() # Should fail - too large result = clipboard.copy("x" * (11 * 1024)) # 11KB assert result == False, "Should reject oversized text" print("✅ Size limit enforced") # Should sanitize null bytes result = clipboard.copy("hello\x00world") assert result == False, "Should reject null bytes" print("✅ Null byte protection working") ``` --- ## Security Checklist - [x] Path traversal protection (data_store) - [x] Path traversal protection (screenshot) - [x] Filename sanitization - [x] Input validation (clipboard) - [x] Size limits (clipboard) - [x] URL validation (http_client) - [x] SSRF protection (http_client) - [x] Secure file permissions - [x] Atomic file writes - [x] Data structure validation - [ ] Plugin signature verification (future) - [ ] Plugin sandboxing (future) - [ ] Audit logging (future) - [ ] Data encryption (future) --- ## Contact For questions about these security fixes, refer to: - `SECURITY_AUDIT_REPORT.md` - Full audit report - `core/security_utils.py` - Security utility classes --- *Security fixes applied by Security Auditor Agent* *EU-Utility Security Hardening 2026*