security: implement pentest remediation (RATE-002, CLI-001)

RATE-002: Proactive rate limit cleanup when entries exceed threshold
- Add RATE_LIMIT_CLEANUP_THRESHOLD config (default 0.8)
- Trigger cleanup before hitting hard limit
- Prevents memory exhaustion under sustained load

CLI-001: Validate clipboard tool paths against trusted directories
- Add TRUSTED_CLIPBOARD_DIRS for Unix system paths
- Add TRUSTED_WINDOWS_PATTERNS for Windows validation
- Reject tools in user-writable locations (PATH hijack prevention)
- Use absolute paths in subprocess calls
This commit is contained in:
Username
2025-12-24 22:03:17 +01:00
parent 89eee3378a
commit 1fbb69d7f9
6 changed files with 240 additions and 6 deletions

View File

@@ -166,6 +166,7 @@ def check_rate_limit(client_ip: str, authenticated: bool = False) -> tuple[bool,
window = current_app.config["RATE_LIMIT_WINDOW"]
max_requests = current_app.config["RATE_LIMIT_MAX"]
max_entries = current_app.config.get("RATE_LIMIT_MAX_ENTRIES", 10000)
cleanup_threshold = current_app.config.get("RATE_LIMIT_CLEANUP_THRESHOLD", 0.8)
if authenticated:
max_requests *= current_app.config.get("RATE_LIMIT_AUTH_MULTIPLIER", 5)
@@ -174,7 +175,15 @@ def check_rate_limit(client_ip: str, authenticated: bool = False) -> tuple[bool,
cutoff = now - window
with _rate_limit_lock:
# RATE-001: Enforce maximum entries to prevent memory exhaustion
entry_count = len(_rate_limit_requests)
# RATE-002: Proactive cleanup when exceeding threshold
threshold_count = int(max_entries * cleanup_threshold)
if entry_count >= threshold_count:
# Clean up expired entries first
_prune_rate_limit_entries(threshold_count // 2, cutoff)
# RATE-001: Hard limit enforcement (fallback if threshold cleanup wasn't enough)
if len(_rate_limit_requests) >= max_entries and client_ip not in _rate_limit_requests:
# Evict oldest entries (those with oldest last request time)
_prune_rate_limit_entries(max_entries // 2, cutoff)