EU-Utility/SECURITY_FIXES_APPLIED.md

9.0 KiB

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:

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:

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:

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:

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)

  1. Data Encryption

    • Encrypt sensitive plugin data at rest
    • Encrypt clipboard history with user password
  2. Rate Limiting

    • Per-plugin API rate limits
    • Screenshot capture rate limiting

Testing Security Fixes

Path Traversal Test

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

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

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

  • Path traversal protection (data_store)
  • Path traversal protection (screenshot)
  • Filename sanitization
  • Input validation (clipboard)
  • Size limits (clipboard)
  • URL validation (http_client)
  • SSRF protection (http_client)
  • Secure file permissions
  • Atomic file writes
  • 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