fix: harden SAC security per audit (0.4.15)
Close audit findings: anti-spoof client IP for login rate limit, JWT/CORS enforce on startup, SSH host-key verification and sudo via stdin, optional WinRM HTTPS, SSE httpOnly cookie auth, ingest body limit, ILIKE escaping, and HMAC API key hashing with legacy SHA-256 fallback.
This commit is contained in:
+13
-4
@@ -1,4 +1,4 @@
|
||||
import asyncio
|
||||
import asyncio
|
||||
import logging
|
||||
from contextlib import asynccontextmanager, suppress
|
||||
from pathlib import Path
|
||||
@@ -13,7 +13,9 @@ from app.api.v1.router import api_router
|
||||
from app.auth.api_key import hash_api_key
|
||||
from app.config import get_settings
|
||||
from app.database import SessionLocal
|
||||
from app.middleware.ingest_body_limit import IngestBodySizeLimitMiddleware
|
||||
from app.models import ApiKey
|
||||
from app.security_bootstrap import validate_security_settings, warn_relaxed_security
|
||||
from app.services.user_auth import bootstrap_admin_user
|
||||
from app.version import APP_VERSION, APP_VERSION_LABEL
|
||||
|
||||
@@ -67,6 +69,9 @@ def bootstrap_stale_remote_actions() -> None:
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(_app: FastAPI):
|
||||
settings = get_settings()
|
||||
validate_security_settings(settings)
|
||||
warn_relaxed_security(settings)
|
||||
logger.info("%s — application startup (version %s)", APP_VERSION_LABEL, APP_VERSION)
|
||||
bootstrap_api_key()
|
||||
bootstrap_users()
|
||||
@@ -74,7 +79,6 @@ async def lifespan(_app: FastAPI):
|
||||
|
||||
stop_scan = asyncio.Event()
|
||||
scan_task: asyncio.Task | None = None
|
||||
settings = get_settings()
|
||||
if settings.sac_host_silence_scan_enabled:
|
||||
from app.jobs.host_silence_background import host_silence_scan_loop
|
||||
|
||||
@@ -108,13 +112,18 @@ def create_app() -> FastAPI:
|
||||
lifespan=lifespan,
|
||||
)
|
||||
origins = [o.strip() for o in settings.cors_origins.split(",") if o.strip()]
|
||||
wildcard = origins == ["*"]
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=origins if origins != ["*"] else ["*"],
|
||||
allow_credentials=True,
|
||||
allow_origins=origins if not wildcard else ["*"],
|
||||
allow_credentials=not wildcard,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
app.add_middleware(
|
||||
IngestBodySizeLimitMiddleware,
|
||||
max_bytes=settings.sac_ingest_max_body_bytes,
|
||||
)
|
||||
from app.api.v1.health import router as health_router
|
||||
|
||||
app.include_router(api_router, prefix="/api/v1")
|
||||
|
||||
Reference in New Issue
Block a user