diff --git a/backend/auth.py b/backend/auth.py index fad4d47..2b60a52 100644 --- a/backend/auth.py +++ b/backend/auth.py @@ -18,6 +18,12 @@ JWT_SECRET = os.getenv("JWT_SECRET", "change-me-in-production") JWT_ALGO = "HS256" JWT_EXPIRY = int(os.getenv("JWT_EXPIRY_DAYS", "30")) +if JWT_SECRET == "change-me-in-production" and os.getenv("ENV") == "production": + raise RuntimeError( + "SICHERHEITSFEHLER: JWT_SECRET ist nicht gesetzt. " + "Bitte JWT_SECRET in .env setzen und Container neu starten." + ) + security = HTTPBearer(auto_error=False) diff --git a/backend/main.py b/backend/main.py index a6c16aa..efdadb6 100644 --- a/backend/main.py +++ b/backend/main.py @@ -3,11 +3,13 @@ BAN YARO — FastAPI Hauptanwendung """ import os +import html import logging from collections import deque from fastapi import FastAPI, Request from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse, JSONResponse +from starlette.middleware.base import BaseHTTPMiddleware from contextlib import asynccontextmanager from database import init_db @@ -61,6 +63,22 @@ app = FastAPI( redoc_url = None, ) +# Globales File-Upload-Limit (20 MB) +_MAX_UPLOAD_BYTES = 20 * 1024 * 1024 + +class _UploadSizeMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request: Request, call_next): + if request.method in ("POST", "PUT", "PATCH"): + cl = request.headers.get("content-length") + if cl and int(cl) > _MAX_UPLOAD_BYTES: + return JSONResponse( + status_code=413, + content={"detail": f"Datei zu groß (max. {_MAX_UPLOAD_BYTES // 1024 // 1024} MB)."} + ) + return await call_next(request) + +app.add_middleware(_UploadSizeMiddleware) + # ------------------------------------------------------------------ # API-Router registrieren (werden nach und nach hinzugefügt) @@ -649,24 +667,25 @@ async def public_dog_page(dog_id: int): except Exception: pass - html = f""" + _s = html.escape # XSS-Schutz für OG-Meta-Tags + _html = f""" - {_og_name} — Ban Yaro - + {_s(_og_name)} — Ban Yaro + - - + + - + - - + +