security: fix critical vulnerabilities and code quality issues
Critical fixes: - init_admin.py: replace hardcoded admin123 password with ADMIN_PASSWORD env var - proxmox_client.py, models.py: change verify_ssl default from False to True - api/proxmox.py: use server.verify_ssl instead of hardcoded verify=False in websocket handler - ssh_client.py: replace AutoAddPolicy (MITM-vulnerable) with WarningPolicy + load_system_host_keys Security hardening: - main.py: add security headers middleware (CSP, X-Frame-Options, HSTS, X-XSS-Protection, Referrer-Policy) - main.py: fix CORS — allow_credentials=True is incompatible with allow_origins=["*"]; read origins from CORS_ORIGINS env var - auth.py, logging_middleware.py: validate X-Forwarded-For/X-Real-IP to prevent IP spoofing Performance: - monitoring_worker.py: wire up cleanup_expired_connections() as hourly scheduled job (was defined but never called) Code quality: - logging_service.py: move `import json` from inside function to module level - ssh_client.py, proxmox_client.py, api/proxmox.py, rbac/migration.py, task_queue_service.py: replace all bare `except:` with `except Exception:` - .env.example, config.py: document ADMIN_PASSWORD and CORS_ORIGINS settings https://claude.ai/code/session_019rK2wvaWg5zXFwmAPPEB7R
This commit is contained in:
@@ -163,24 +163,47 @@ def create_app() -> FastAPI:
|
||||
)
|
||||
|
||||
# Add CORS middleware
|
||||
cors_origins = [o.strip() for o in settings.CORS_ORIGINS.split(",") if o.strip()]
|
||||
# allow_credentials=True is incompatible with allow_origins=["*"] per the CORS spec.
|
||||
# Disable credentials when wildcard origin is configured.
|
||||
allow_credentials = cors_origins != ["*"]
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"], # In production, specify exact origins
|
||||
allow_credentials=True,
|
||||
allow_origins=cors_origins,
|
||||
allow_credentials=allow_credentials,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
|
||||
# Add request logging middleware
|
||||
app.add_middleware(RequestLoggingMiddleware, enable_api_logging=True)
|
||||
|
||||
|
||||
# Add language detection middleware
|
||||
app.add_middleware(LanguageMiddleware)
|
||||
|
||||
|
||||
# Templates
|
||||
templates = Jinja2Templates(directory="app/templates")
|
||||
|
||||
|
||||
# Security headers middleware
|
||||
@app.middleware("http")
|
||||
async def add_security_headers(request: Request, call_next):
|
||||
response = await call_next(request)
|
||||
response.headers["X-Content-Type-Options"] = "nosniff"
|
||||
response.headers["X-Frame-Options"] = "SAMEORIGIN"
|
||||
response.headers["X-XSS-Protection"] = "1; mode=block"
|
||||
response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
|
||||
response.headers["Content-Security-Policy"] = (
|
||||
"default-src 'self'; "
|
||||
"script-src 'self' 'unsafe-inline' 'unsafe-eval'; "
|
||||
"style-src 'self' 'unsafe-inline'; "
|
||||
"img-src 'self' data: blob:; "
|
||||
"connect-src 'self' wss: ws:; "
|
||||
"font-src 'self' data:; "
|
||||
"frame-ancestors 'self';"
|
||||
)
|
||||
if not settings.DEBUG:
|
||||
response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
|
||||
return response
|
||||
|
||||
# Custom exception handler
|
||||
@app.exception_handler(Exception)
|
||||
|
||||
Reference in New Issue
Block a user