EU-Utility/SECURITY_FIXES_APPLIED.md

320 lines
9.0 KiB
Markdown

# 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*