FlawOpen

flawopen.com/Teardowns/cve-2026-77244-mcp-atlassian-http-auth-bypass

● CVE-2026-77244 · CVSS 10.0[1] · Crítica
Pesquisa · FlawOpen

CVE-2026-77244: acesso HTTP sem autenticação no mcp-atlassian

CVE-2026-77244 permitia que chamadas sem autenticação alcançassem os manipuladores HTTP do projeto comunitário mcp-atlassian, que podiam usar as credenciais Jira ou Confluence configuradas no ambiente do operador. A correção principal saiu na versão 0.22.0; usuários de SSE precisam da 0.23.1 ou posterior para outra falha de transporte relacionada.[1], [4], [5], [6]

Vetor CVSSCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N[1]
💡 Explicação em Linguagem Simples (ELI5)

A recepção deve conferir o crachá de quem visita antes de abrir a porta reservada à equipe. No fluxo antigo, se não houvesse crachá, a recepcionista emprestava sua chave mestra. A falha combinava duas lacunas: uma requisição HTTP podia chegar às ferramentas sem identidade verificada, e elas podiam usar as credenciais Atlassian compartilhadas do operador. A correção rejeita requisições HTTP não autenticadas e exige adesão explícita para esse fallback de credenciais.[1], [3]

Conceitos Centrais e Termos

Transporte MCP
Canal que leva requisições do Model Context Protocol entre cliente e servidor. Esta CVE afeta o transporte HTTP do mcp-atlassian; o aviso não afeta stdio.[1], [4]
Fallback de credenciais globais
Uso de credenciais Jira ou Confluence configuradas no ambiente do servidor quando a requisição não tem identidade própria. Em HTTP acessível remotamente, isso pode transformar uma requisição anônima em uma ação como operador.[1], [4]
Limite de autenticação
Verificação no servidor que estabelece a identidade antes de permitir que a requisição alcance ferramentas protegidas. Alcance de rede, token não vazio ou confiança presumida em proxy não comprovam identidade.[1], [7]
CWE-287
Autenticação inadequada: o aplicativo não comprova suficientemente a identidade alegada antes de conceder acesso.[1], [7]
CWE-303
O verificador de token implementa a autenticação incorretamente: aceita qualquer token não vazio sem confirmar sua validade.[1], [9]
CWE-862
A requisição HTTP podia alcançar manipuladores de ferramentas privilegiadas sem uma verificação de autorização que exigisse uma identidade de usuário confirmada.[1], [10]

Mapeamentos de frameworks

Análise de Causa Raiz

O aviso de segurança do GitHub descreve uma cadeia no projeto comunitário mcp-atlassian, não uma vulnerabilidade de produto da Atlassian. Nas versões anteriores a 0.22.0, o middleware HTTP podia encaminhar uma requisição sem identidade de usuário aos manipuladores de ferramentas. Quando a implantação usava credenciais do operador por variáveis de ambiente, JiraFetcher ou ConfluenceFetcher podia recorrer a essas credenciais globais. O aviso também documenta um verificador de token opaco que aceitava qualquer string não vazia; isso não comprova a identidade real do chamador. O limite precisa proteger tanto a identidade da requisição quanto a seleção de credenciais: usuário ausente ou não verificado nunca deve herdar a credencial privilegiada do operador. A correção 0.22.0 retorna HTTP 401 para requisições MCP streamable-HTTP sem autenticação e impede o fallback de credenciais globais em contexto HTTP, a menos que ALLOW_GLOBAL_CRED_FALLBACK=true seja configurado explicitamente para uma implantação de usuário único. O comportamento stdio não muda. Separadamente, GHSA-5j8j-256g-vvp5 descreve um problema de correspondência de caminhos SSE corrigido na 0.23.1; não é CVE-2026-77244. Atualize implantações SSE para 0.23.1 ou posterior e não presuma que a correção da CVE na 0.22.0 também resolve esse outro aviso. O aviso não confirma exploração; este artigo não afirma que houve invasão real. O aviso da CVE lista CWE-287, CWE-303 e CWE-862 para as falhas de autenticação, verificação de token e autorização desta cadeia. O aviso credita a descoberta a crazydude123.[1], [3], [4], [5], [6], [7], [9], [10]

Fluxo de Ataque Passo a Paso

Passo 1

Um endpoint HTTP MCP está acessível

A implantação executa o servidor comunitário mcp-atlassian em HTTP e uma parte não autenticada consegue alcançar o transporte. Implantações somente stdio estão fora do caminho afetado por esta CVE.[1]

Passo 2

A requisição chega à ferramenta sem usuário verificado

Antes da 0.22.0, uma requisição HTTP sem identidade própria podia passar pelo middleware em vez de ser rejeitada no limite do transporte. O aviso também informa que uma string não vazia não era verificada como identidade independente.[1], [3]

Passo 3

A ferramenta seleciona credenciais compartilhadas do operador

Se não houver identidade própria e o servidor tiver credenciais Jira ou Confluence no ambiente, o fetcher pode usar as credenciais globais. A requisição pode então exercer as permissões das ferramentas habilitadas para o operador; o impacto depende dos privilégios e da configuração.[1], [3]

Passo 4

Rejeite na borda e falhe fechado na seleção de credencial

A versão 0.22.0 retorna HTTP 401 para requisições streamable-HTTP sem autenticação e bloqueia o fallback global em contexto HTTP, salvo adesão explícita. Para SSE, use 0.23.1 ou posterior, que corrige a falha separada de correspondência de caminho.[1], [4], [5], [6]

Código-Fonte: Vulnerável vs. Seguro

Trecho esquemático e condensado do fluxo, não cópia literal das funções completas. O patch upstream adiciona HTTP 401 no limite do transporte e uma segunda proteção antes de devolver o fetcher global em contexto HTTP; ambas exigem a opção explícita ALLOW_GLOBAL_CRED_FALLBACK.[1], [3], [4]

IMPLEMENTAÇÃO VULNERÁVEL
# Representação simplificada do fluxo de controle afetado.
async def handle_request(scope, ctx):
    user_identity = scope.get("state", {}).get("user_atlassian_auth_type")
    # A ausência de identidade não era rejeitada na fronteira 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)
    # Usa como alternativa as credenciais do operador configuradas no ambiente.
    return fetcher_from_config(global_config)
PATCH SEGURO E ROBUSTO
# Representação focada das proteções integradas na versão 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)

Lista de Verificação de Segurança para Engenharia

Fontes