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:
@@ -0,0 +1,37 @@
|
||||
"""httpOnly cookie auth for SSE (EventSource cannot send Authorization header)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import Response
|
||||
|
||||
from app.config import Settings
|
||||
|
||||
STREAM_COOKIE_NAME = "sac_stream"
|
||||
STREAM_COOKIE_PATH = "/api/v1/stream"
|
||||
|
||||
|
||||
def stream_cookie_kwargs(settings: Settings) -> dict[str, object]:
|
||||
secure = settings.sac_public_url.lower().startswith("https://")
|
||||
return {
|
||||
"key": STREAM_COOKIE_NAME,
|
||||
"httponly": True,
|
||||
"secure": secure,
|
||||
"samesite": "strict",
|
||||
"path": STREAM_COOKIE_PATH,
|
||||
"max_age": max(60, int(settings.jwt_expire_minutes) * 60),
|
||||
}
|
||||
|
||||
|
||||
def set_stream_auth_cookie(response: Response, token: str, settings: Settings) -> None:
|
||||
response.set_cookie(value=token, **stream_cookie_kwargs(settings))
|
||||
|
||||
|
||||
def clear_stream_auth_cookie(response: Response, settings: Settings) -> None:
|
||||
kwargs = stream_cookie_kwargs(settings)
|
||||
response.delete_cookie(
|
||||
key=kwargs["key"],
|
||||
path=kwargs["path"],
|
||||
secure=bool(kwargs["secure"]),
|
||||
httponly=True,
|
||||
samesite="strict",
|
||||
)
|
||||
Reference in New Issue
Block a user