flawopen.com/Teardowns/cve-2026-77244-mcp-atlassian-http-auth-bypass
CVE-2026-77244 : accès HTTP non authentifié à mcp-atlassian
CVE-2026-77244 permettait à des appels non authentifiés d’atteindre les gestionnaires HTTP du projet communautaire mcp-atlassian, qui pouvaient utiliser les identifiants Jira ou Confluence configurés dans l’environnement de l’opérateur. Le correctif principal est arrivé en 0.22.0 ; les utilisateurs de SSE doivent passer à 0.23.1 ou ultérieur pour une faille de transport distincte.[1], [4], [5], [6]
L’accueil doit vérifier le badge d’un visiteur avant d’ouvrir une porte réservée au personnel. Dans l’ancien flux, sans badge, l’accueil prêtait son passe-partout. Le défaut associait deux contrôles absents : une requête HTTP pouvait atteindre les outils sans identité vérifiée, puis ceux-ci pouvaient utiliser les identifiants Atlassian partagés de l’opérateur. Le correctif rejette les requêtes HTTP non authentifiées et rend ce recours aux identifiants explicite.[1], [3]
Concepts Clés et Termes
Transport MCP- Canal qui transporte les requêtes Model Context Protocol entre un client et un serveur. Cette CVE concerne le transport HTTP de mcp-atlassian ; l’avis ne touche pas stdio.[1], [4]
Repli sur les identifiants globaux- Utilisation des identifiants Jira ou Confluence de l’environnement du serveur lorsqu’une requête n’a pas d’identité par utilisateur. Sur un HTTP accessible à distance, une requête anonyme peut alors agir comme l’opérateur.[1], [4]
Frontière d’authentification- Contrôle côté serveur qui établit l’identité avant qu’une requête n’atteigne les gestionnaires protégés. L’accès réseau, un jeton non vide ou une confiance supposée envers un proxy ne prouvent pas seuls une identité.[1], [7]
CWE-287- Authentification incorrecte : l’application ne prouve pas suffisamment l’identité revendiquée avant d’accorder l’accès.[1], [7]
Correspondances de référentiels
Analyse de Cause Racine
L’avis GitHub décrit une chaîne dans le projet communautaire mcp-atlassian, pas une vulnérabilité d’un produit Atlassian. Avant 0.22.0, le middleware HTTP pouvait laisser une requête sans identité utilisateur atteindre les gestionnaires d’outils. Si le déploiement utilisait les identifiants de l’opérateur issus des variables d’environnement, JiraFetcher ou ConfluenceFetcher pouvait les reprendre. L’avis décrit aussi un vérificateur de jetons opaques qui acceptait toute chaîne non vide ; cela ne prouve pas l’identité réelle de l’appelant. La frontière doit protéger ensemble l’identité de la requête et le choix des identifiants : un utilisateur absent ou non vérifié ne doit jamais hériter de l’identifiant privilégié de l’opérateur. Le correctif 0.22.0 renvoie HTTP 401 aux requêtes MCP streamable-HTTP non authentifiées et bloque le repli global en contexte HTTP, sauf configuration explicite de ALLOW_GLOBAL_CRED_FALLBACK=true pour un déploiement mono-utilisateur. Le comportement stdio reste inchangé. Séparément, GHSA-5j8j-256g-vvp5 décrit un défaut de correspondance des chemins SSE corrigé en 0.23.1 ; il ne s’agit pas de CVE-2026-77244. Passez les déploiements SSE à 0.23.1 ou ultérieur et ne supposez pas que le correctif CVE 0.22.0 règle aussi cet autre avis. L’avis ne confirme pas d’exploitation ; cet article n’affirme pas qu’une intrusion réelle a eu lieu. L’avis CVE attribue les CWE-287, CWE-303 et CWE-862 aux défauts d’authentification, de vérification du jeton et d’autorisation de cette chaîne. L’avis attribue le signalement à crazydude123.[1], [3], [4], [5], [6], [7], [9], [10]
Déroulement de l'Attaque Étape par Étape
Un endpoint HTTP MCP est accessible
Le déploiement exécute le serveur communautaire mcp-atlassian en HTTP et une partie non authentifiée peut atteindre son transport. Les déploiements stdio uniquement sont hors du chemin concerné par cette CVE.[1]
L’outil choisit les identifiants partagés de l’opérateur
Sans identité propre et si le serveur possède des identifiants Jira ou Confluence dans son environnement, le fetcher peut utiliser les identifiants globaux. La requête peut alors exercer les permissions des outils activés pour l’opérateur ; l’impact exact dépend de ses droits et de la configuration.[1], [3]
Rejeter au transport et échouer en mode fermé lors du choix d’identifiants
La version 0.22.0 renvoie HTTP 401 aux requêtes streamable-HTTP non authentifiées et bloque le repli global en contexte HTTP sauf activation explicite. Pour SSE, installez 0.23.1 ou ultérieur, qui corrige le défaut distinct de correspondance de chemin.[1], [4], [5], [6]
Code Source : Vulnérable vs Sécurisé
Représentation condensée du flux, pas copie littérale des fonctions complètes. Le correctif amont ajoute HTTP 401 à la frontière du transport et une seconde protection avant de fournir le fetcher global en contexte HTTP ; les deux exigent l’option explicite ALLOW_GLOBAL_CRED_FALLBACK.[1], [3], [4]
# Représentation simplifiée du flux de contrôle concerné.
async def handle_request(scope, ctx):
user_identity = scope.get("state", {}).get("user_atlassian_auth_type")
# L’absence d’identité n’était pas rejetée à la frontière HTTP.
return await call_tool_handler(ctx, user_identity=user_identity)
def get_fetcher(user_identity, global_config):
if user_identity:
return fetcher_for_user(user_identity)
# Utilise les identifiants de l’opérateur configurés dans l’environnement en secours.
return fetcher_from_config(global_config)
# Représentation ciblée des protections intégrées dans la version 0.22.0.
async def handle_request(scope, ctx):
user_identity = scope.get("state", {}).get("user_atlassian_auth_type")
if is_mcp_http_post(scope) and not user_identity and not allow_global_fallback():
return http_401("Authentication required")
return await call_tool_handler(ctx, user_identity=user_identity)
def get_fetcher(user_identity, global_config, *, in_http_context):
if user_identity:
return fetcher_for_user(user_identity)
if in_http_context and not allow_global_fallback():
raise PermissionError("Refusing operator credentials for an unauthenticated HTTP request")
return fetcher_from_config(global_config)
Liste de Contrôle de Sécurité pour l'Ingénierie
- ✓Mettez à jour
mcp-atlassiandes versions antérieures à 0.22.0 vers au moins 0.22.0 pourCVE-2026-77244; si vous utilisez--transport sse, passez à 0.23.1 ou ultérieur pour la correction distincte GHSA-5j8j-256g-vvp5.[1], [4], [5], [6] - ✓Repérez chaque exposition HTTP : liaison directe, port de conteneur, ingress, répartiteur, VPN ou tunnel de développement. Restreignez l’accès pendant la mise à jour.[1]
- ✓Laissez
ALLOW_GLOBAL_CRED_FALLBACKabsent ou à false pour les déploiements HTTP multi-utilisateurs ou accessibles à distance. Ne l’activez que pour un déploiement mono-utilisateur délibéré et avec une frontière documentée.[1], [4] - ✓Exigez et vérifiez une véritable identité utilisateur avant d’exécuter des outils. Un jeton non vide, l’emplacement réseau ou un en-tête proxy ne prouvent pas une identité sans validation explicite.[1], [7]
- ✓Ajoutez des tests confirmant que l’absence d’identité renvoie HTTP 401 avant tout gestionnaire d’outil et que le choix du fetcher HTTP refuse les identifiants d’environnement sans activation explicite.[3], [4]
- ✓Testez streamable HTTP et SSE séparément : le défaut d’authentification des chemins SSE est un avis distinct, corrigé en 0.23.1, et pas seulement par le correctif CVE 0.22.0.[5], [6]
- ✓Si une instance vulnérable était accessible à des personnes non fiables, auditez l’activité Jira et Confluence de la compte de service et renouvelez les identifiants si une exposition est plausible.[1]
Sources
- Avis de sécurité GitHub GHSA-wrhw-j3f9-8vc6 — CVE-2026-77244
- Fiche CVE.org CVE-2026-77244
- PR amont #1448 et commit f500f5b
- Version mcp-atlassian v0.22.0
- Avis SSE distinct GHSA-5j8j-256g-vvp5
- Version mcp-atlassian v0.23.1 (correctif d’authentification SSE)
- MITRE CWE-287: Improper Authentication
- Couverture ThreatFrontier, 2 octobre 2026
- MITRE CWE-303: Incorrect Implementation of Authentication Algorithm
- MITRE CWE-862: Missing Authorization