Implement security hardening across frontend, backend, and infrastructure
- nginx: add X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, and Referrer-Policy headers on all responses; rate limit /api/auth/login to 5 req/min per IP (burst 3) to prevent brute force - frontend: add escHtml() utility to api.js; use it on all notes fields across dashboard, log, history, flock, and budget pages to prevent XSS - log.js: fix broken loadRecent() call referencing removed #recent-body element; replaced with loadHistory() from history.js - schemas.py: raise minimum password length from 6 to 10 characters - admin.py: add audit logging for password reset, disable, delete, and impersonate actions; fix impersonate to use named admin param for logging - main.py: add startup env validation — exits with clear error if any required env var is missing; configure structured logging to stdout - docker-compose.yml: add log rotation (10 MB / 3 files) to all services Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import logging
|
||||
import sys
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI
|
||||
@@ -12,8 +13,21 @@ from auth import hash_password
|
||||
from routers import eggs, flock, feed, stats, other
|
||||
from routers import auth_router, admin
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
|
||||
stream=sys.stdout,
|
||||
)
|
||||
logger = logging.getLogger("yolkbook")
|
||||
|
||||
_REQUIRED_ENV = ["ADMIN_USERNAME", "ADMIN_PASSWORD", "JWT_SECRET", "DATABASE_URL"]
|
||||
|
||||
def _validate_env():
|
||||
missing = [k for k in _REQUIRED_ENV if not os.environ.get(k)]
|
||||
if missing:
|
||||
logger.critical("Missing required environment variables: %s", ", ".join(missing))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def _seed_admin():
|
||||
"""Create or update the admin user from environment variables.
|
||||
@@ -68,6 +82,7 @@ def _run_migrations():
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
_validate_env()
|
||||
Base.metadata.create_all(bind=engine)
|
||||
_run_migrations()
|
||||
_seed_admin()
|
||||
|
||||
Reference in New Issue
Block a user