Files
security-alert-center/backend/app/security_bootstrap.py
T
PapaTramp 80320ae698 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.
2026-07-07 19:32:12 +10:00

53 lines
1.7 KiB
Python

"""Fail-fast checks for insecure production defaults."""
from __future__ import annotations
import logging
from urllib.parse import urlparse
from app.config import Settings
logger = logging.getLogger("sac")
_WEAK_JWT_SECRETS = frozenset(
{
"",
"change-me-in-production",
"change-me-openssl-rand-hex-32",
"CHANGE_ME_openssl_rand_hex_32",
}
)
def _is_local_dev_url(public_url: str) -> bool:
parsed = urlparse(public_url.strip() or "http://localhost:8000")
host = (parsed.hostname or "").lower()
return host in {"localhost", "127.0.0.1", "::1", "testserver"}
def validate_security_settings(settings: Settings) -> None:
"""Raise on dangerous defaults when SAC_SECURITY_ENFORCE=true."""
if not settings.sac_security_enforce:
return
if settings.jwt_secret in _WEAK_JWT_SECRETS:
raise RuntimeError(
"JWT_SECRET is missing or uses an insecure default. "
"Set a random value in sac-api.env (openssl rand -hex 32)."
)
if settings.cors_origins.strip() == "*" and not _is_local_dev_url(settings.sac_public_url):
raise RuntimeError(
"CORS_ORIGINS=* is not allowed with SAC_SECURITY_ENFORCE=true on non-local SAC_PUBLIC_URL. "
"Set CORS_ORIGINS to your UI origin, e.g. https://sac.example.com"
)
def warn_relaxed_security(settings: Settings) -> None:
if settings.sac_security_enforce:
return
if settings.jwt_secret in _WEAK_JWT_SECRETS:
logger.warning("JWT_SECRET uses insecure default — set a strong secret before production")
if settings.cors_origins.strip() == "*":
logger.warning("CORS_ORIGINS=* — restrict to explicit origins in production")