7.76.1 — correctif : /mcp exempté du CSRF (client Bearer machine-à-machine)
Le middleware CSRF rejetait tout POST /mcp en 403 avant la route ; les tests passaient car leur client porte session + CSRF. Test de régression : client anonyme Bearer seul (200 avec jeton, 401 sans).
This commit is contained in:
@@ -20,6 +20,11 @@ class CSRFMiddleware(BaseHTTPMiddleware):
|
||||
SAFE_METHODS = {"GET", "HEAD", "OPTIONS"}
|
||||
# NOTE: ``/scim/v2`` is Bearer-token only (no cookie auth), so CSRF does not
|
||||
# apply — IdP SCIM clients (Okta, Entra) cannot send an X-CSRF-Token.
|
||||
# Même logique pour ``/mcp`` (Fusion, 7.76.1) : le serveur MCP est
|
||||
# machine-à-machine, authentifié par les jetons d'API personnels
|
||||
# (Bearer) — le service d'agents ne peut pas envoyer de X-CSRF-Token.
|
||||
# Sans cette exemption, tout POST /mcp mourait en 403 avant la route
|
||||
# (les tests passaient : leur client porte session + CSRF).
|
||||
# A19 — LISTE FINALE : plus aucun préfixe cookie-auth n'est exempté.
|
||||
# Tous les appels non-GET du front envoient désormais `X-CSRF-Token`
|
||||
# (46 sites équipés en v7.3.6 : agent_panel, settings, local_workspace,
|
||||
@@ -30,7 +35,7 @@ class CSRFMiddleware(BaseHTTPMiddleware):
|
||||
# - publics : /s/ (sites), /f/ (forms)
|
||||
# - infra/diag : /api/csrf-token (le jeton lui-même), /api/frontend-error
|
||||
EXCLUDED_PATHS = {
|
||||
"/api/webhook", "/api/v1", "/api/v2", "/scim/v2",
|
||||
"/api/webhook", "/api/v1", "/api/v2", "/scim/v2", "/mcp",
|
||||
"/auth/callback", "/auth/register", "/auth/local-login", "/auth/local-verify",
|
||||
"/auth/2fa", "/auth/saml", "/auth/oidc", "/auth/webauthn",
|
||||
"/s/", "/f/", "/api/csrf-token", "/api/frontend-error",
|
||||
|
||||
@@ -156,6 +156,21 @@ def test_mcp_ecriture_sans_jeton_401(client, donnees):
|
||||
assert r.status_code == 401
|
||||
|
||||
|
||||
def test_mcp_client_bearer_sans_session_ni_csrf(client, jeton, donnees):
|
||||
"""Régression 7.76.1 : un vrai client MCP est machine-à-machine
|
||||
(Bearer seul, ni session ni jeton CSRF) — exactement le service
|
||||
d'agents. Le client de test habituel porte une session + un CSRF,
|
||||
ce qui masquait le 403 du middleware en production."""
|
||||
from tests.conftest import anon
|
||||
anon(client)
|
||||
r = _rpc(client, jeton, 60, "initialize", {})
|
||||
assert r.status_code == 200, r.text
|
||||
cols = _appel(client, jeton, 61, "list_collections")
|
||||
assert any(c["name"] == "Projet Alpha" for c in cols)
|
||||
r = _rpc(client, None, 62, "tools/list")
|
||||
assert r.status_code == 401, r.text
|
||||
|
||||
|
||||
def test_mcp_info_get(client, jeton):
|
||||
r = client.get("/mcp")
|
||||
assert r.status_code == 200
|
||||
|
||||
Reference in New Issue
Block a user