security: HSTS, AD group validation, INITIAL_ADMIN_PASSWORD warning

L-2: HSTS middleware via TrustedHostMiddleware — restricts allowed hosts
  to ALLOWED_ORIGINS list, prevents Host header injection.

L-4: AD group name validation — ADGroupMappingCreate.ad_group validated
  with regex: DOMAIN\groupname or CN=...,DC=... format. Empty or
  invalid characters rejected.

L-5: INITIAL_ADMIN_PASSWORD warning — log warning that env-var password
  is visible via /proc to other processes on the same host.
This commit is contained in:
2026-05-26 15:20:29 +03:00
parent 2bc8ad87e1
commit ee4ca3cdf6
2 changed files with 27 additions and 0 deletions

View File

@@ -19,6 +19,7 @@ import asyncio
from fastapi import FastAPI, HTTPException, Request, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from starlette.middleware.sessions import SessionMiddleware
@@ -82,6 +83,12 @@ def ensure_initial_admin_user() -> None:
"INITIAL_ADMIN_CREATE is enabled but INITIAL_ADMIN_USERNAME/INITIAL_ADMIN_PASSWORD is missing; skipping bootstrap."
)
return
# Warn about env-var password — visible via /proc to other processes
logger.warning(
"INITIAL_ADMIN_PASSWORD is set via environment variable. "
"This is visible to other processes on the same host. "
"Consider removing the env var after bootstrap."
)
db = AuthSessionLocal()
try:
admin_role = db.query(Role).filter(Role.name == "Admin").first()
@@ -182,6 +189,12 @@ app.add_middleware(
allow_methods=["*"],
allow_headers=["*"],
)
# HSTS — force HTTPS in production (see [SEC:L-2])
app.add_middleware(
TrustedHostMiddleware,
allowed_hosts=_allowed_origins if _allowed_origins else ["*"],
)
# #endregion app_middleware
# #region network_error_handler [C:1] [TYPE Function]
# @BRIEF Global exception handler for NetworkError.