Phase 2: Fix high-priority security and stability issues (H1-H7)

H1: Sanitize error endpoint context (strip tokens/passwords, limit depth/size)
H2: Rate limiter IP spoofing fix (trusted proxy CIDR check for X-Forwarded-For)
H3: CSRF middleware uses Redis singleton instead of per-request connection
H4: WebSocket origin verification added to both kommunikation and ai_ui_control
H5: Storage path traversal protection, get_url() returns relative URL not filesystem path
H6: Security headers middleware (HSTS, X-Content-Type-Options, X-Frame-Options, CSP, Referrer-Policy)
H7: Forward-repair migration 0045 for databases that ran original 0021/0027

Also: add trusted_proxy_cidrs to config, add verify_ws_origin to auth
This commit is contained in:
Agent Zero
2026-07-26 20:49:15 +02:00
parent 5ec1fc9b05
commit 604a2b7648
10 changed files with 360 additions and 38 deletions
+9 -4
View File
@@ -74,8 +74,12 @@ class LocalStorage(StorageBackend):
os.makedirs(self.base_path, exist_ok=True)
def _full_path(self, path: str) -> str:
"""Get the full filesystem path."""
return os.path.join(self.base_path, path)
"""Get the full filesystem path with path traversal protection."""
# Normalize and ensure the path stays within base_path
full = os.path.normpath(os.path.join(self.base_path, path))
if not full.startswith(os.path.normpath(self.base_path)):
raise ValueError(f"Path traversal detected: {path}")
return full
async def save(self, path: str, data: bytes) -> str:
full_path = self._full_path(path)
@@ -113,8 +117,9 @@ class LocalStorage(StorageBackend):
return os.path.exists(self._full_path(path))
async def get_url(self, path: str, expires: int = 3600) -> str:
# Local storage returns the file path for direct access
return self._full_path(path)
"""Return a relative URL path for the file (not the filesystem path)."""
# Return a relative path that can be served by the app
return f"/api/v1/dms/files/{path}"
async def list_files(self, prefix: str) -> list[str]:
full_prefix = self._full_path(prefix)