From b91ee5bf1bb90e209e7b1faf5d9a04445f1d3f0d Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Wed, 16 Sep 2026 00:49:37 +0200 Subject: [PATCH] fix(security): Bearer-Requests von CSRF-Middleware ausnehmen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die CSRF-Middleware verlangte Origin+X-CSRF-Token auf allen unsafe Requests — auch auf Bearer-authentifizierten API-Calls (External-Agent- API, MCP, Integrationen). Externe Systeme senden nie Origin/CSRF, dadurch war /api/v1/external/agent/* faktisch unbrauchbar (403). Fix: Authorization: Bearer-Header-Requests skippen die CSRF-Pruefung. Bearer ist CSRF-immun per Design: Browser haengen den Authorization- Header niemals automatisch an, Cross-Site-Requests koennen ihn nicht schmuggeln. Session-Cookie-Requests (SPA) laufen unverändert durch die volle Origin+Double-Submit-Pruefung. Regression: pytest test_auth.py 11/11, ruff clean --- app/core/middleware.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/core/middleware.py b/app/core/middleware.py index c6b3b74..37e7b82 100644 --- a/app/core/middleware.py +++ b/app/core/middleware.py @@ -74,6 +74,15 @@ class CSRFMiddleware(BaseHTTPMiddleware): if request.headers.get("upgrade", "").lower() == "websocket": return await call_next(request) + # Bearer-token requests are CSRF-immune by design: the Authorization + # header is never attached automatically by browsers, so cross-site + # requests cannot forge it. Exempts programmatic API clients + # (external agent API, MCP, integrations) from Origin+CSRF checks — + # they authenticate via get_current_user_bearer instead. + auth_header = request.headers.get("authorization", "") + if auth_header.startswith("Bearer "): + return await call_next(request) + if request.method in self.UNSAFE_METHODS: # 1. Origin header check origin = request.headers.get("origin")