flawopen.com/Teardowns/cve-2026-77244-mcp-atlassian-http-auth-bypass
CVE-2026-77244: mcp-atlassian Unauthenticated HTTP Tool Access
CVE-2026-77244 let unauthenticated callers reach the community mcp-atlassian HTTP tool handlers, which could fall back to the operator's environment-configured Jira or Confluence credentials. The maintainer fixed this in 0.22.0; SSE users need 0.23.1 or later for a separate related transport flaw.[1], [4], [5], [6]
A reception desk is supposed to check a visitor badge before opening a staff-only door. If no badge is present, the old workflow borrowed the receptionist's master key and opened the door anyway. The flaw joined two missing checks: HTTP requests could reach the tools without a verified user identity, and the tools could use the operator's shared Atlassian credentials. The fix rejects unauthenticated HTTP requests and makes that credential fallback opt-in.[1], [3]
Core Concepts & Subsystem Terms
MCP transport- The channel that carries Model Context Protocol requests between a client and server. This CVE concerns the mcp-atlassian HTTP transport; stdio is not affected by this advisory.[1], [4]
Global credential fallback- Using Jira or Confluence credentials configured in the server environment when a request has no per-user identity. In a remotely reachable HTTP deployment, this can turn an unauthenticated request into an action as the operator.[1], [4]
Authentication boundary- The server-side check that must establish a caller's identity before a request reaches protected tool handlers. Network reachability, a non-empty token string, or a trusted proxy assumption is not identity verification by itself.[1], [7]
CWE-287- Improper Authentication: the application does not adequately prove the identity claimed by an actor before granting access.[1], [7]
Framework mappings
Root Cause Analysis
The GitHub security advisory describes a chain in community project mcp-atlassian, not an Atlassian product vulnerability. In affected versions before 0.22.0, the HTTP middleware could pass a request with no user identity to tool handlers. When the deployment used operator credentials from environment variables, JiraFetcher or ConfluenceFetcher could fall back to those global credentials. The advisory also documents an opaque token verifier that accepted any non-empty string; that behavior is not proof of a real caller identity. The security boundary must be the request identity and credential-selection logic together: a missing or unverified user must never inherit the operator's privileged credential. The merged 0.22.0 fix rejects unauthenticated streamable-HTTP MCP POSTs with HTTP 401 and refuses global credential fallback in HTTP context unless ALLOW_GLOBAL_CRED_FALLBACK=true is explicitly configured for a single-user deployment. Stdio behavior is unchanged. Separately, GHSA-5j8j-256g-vvp5 describes an SSE-path middleware mismatch fixed in 0.23.1; it is not CVE-2026-77244. Upgrade SSE deployments to 0.23.1 or later, and do not infer that the CVE's 0.22.0 patch also fixes that separate advisory. The advisory reports no confirmed exploitation status; this article does not claim a real-world breach. The CVE advisory lists CWE-287, CWE-303, and CWE-862 for the authentication, token-verification, and authorization failures in this chain. The advisory credits crazydude123 as the reporter.[1], [3], [4], [5], [6], [7], [9], [10]
Step-by-Step Attack Flow
An HTTP MCP endpoint is reachable
The deployment runs the community mcp-atlassian server over HTTP and an unauthenticated party can reach its transport. Stdio-only deployments are outside this CVE's affected path.[1]
A tool selects shared operator credentials
If no per-user identity is present and the server has Jira or Confluence credentials in its environment, the fetcher may use those global credentials. The request can then exercise the operator's enabled tool permissions; the exact impact follows that account's privileges and configured tools.[1], [3]
Reject at the transport and fail closed at credential selection
Version 0.22.0 returns HTTP 401 for unauthenticated streamable-HTTP requests and blocks global fallback in HTTP context unless explicitly opted in. For SSE, install 0.23.1 or later because its separate path-matching authentication flaw was fixed there.[1], [4], [5], [6]
Source Code: Flaw vs. Secure Implementation
These are condensed control-flow representations, not verbatim full functions. The upstream patch adds a transport-boundary 401 and a second guard before returning the global Jira/Confluence fetcher in HTTP context; both require the explicit ALLOW_GLOBAL_CRED_FALLBACK opt-in to bypass. The dual check prevents an unauthenticated request from reaching a tool and prevents a downstream identity gap from silently selecting the operator's credentials.[1], [3], [4]
Source excerpt: src/mcp_atlassian/servers/main.py and dependencies.py — HTTP authentication boundary and fetcher fallback
# Simplified representation of the affected control flow.
async def handle_request(scope, ctx):
user_identity = scope.get("state", {}).get("user_atlassian_auth_type")
# Missing identity was not rejected at the HTTP boundary.
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)
# Falls back to operator credentials from environment configuration.
return fetcher_from_config(global_config)
# Focused representation of the merged 0.22.0 safeguards.
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)
Engineering & System Hardening Checklist
- ✓Upgrade
mcp-atlassianversions before 0.22.0 to at least 0.22.0 forCVE-2026-77244; if using--transport sse, upgrade to 0.23.1 or later for the separate GHSA-5j8j-256g-vvp5 fix.[1], [4], [5], [6] - ✓Identify every HTTP exposure path: direct host binding, container port mapping, ingress, load balancer, VPN, or development tunnel. Restrict access while upgrading.[1]
- ✓Keep
ALLOW_GLOBAL_CRED_FALLBACKunset or false for multi-user and remotely reachable HTTP deployments. Enable it only for an intentionally single-user deployment with a documented boundary.[1], [4] - ✓Require and verify a real per-user identity before invoking tools. Do not treat a non-empty opaque token, a network location, or a proxy header as proof unless its trust and validation are explicit.[1], [7]
- ✓Add regression tests asserting that missing identity returns 401 before any tool handler runs and that HTTP fetcher selection refuses environment credentials without explicit opt-in.[3], [4]
- ✓Test streamable HTTP and SSE separately: the SSE authentication-path mismatch is a distinct advisory and was fixed in 0.23.1, not by the 0.22.0 CVE patch alone.[5], [6]
- ✓If an affected instance was reachable by untrusted callers, audit Jira and Confluence activity for actions performed by the configured service account, then rotate its API credentials if exposure is plausible.[1]
Sources
- GitHub Security Advisory GHSA-wrhw-j3f9-8vc6 — CVE-2026-77244
- CVE.org record CVE-2026-77244
- Upstream security fix PR #1448 and commit f500f5b
- mcp-atlassian release v0.22.0
- Separate SSE authentication advisory GHSA-5j8j-256g-vvp5
- mcp-atlassian release v0.23.1 (SSE authentication fix)
- MITRE CWE-287: Improper Authentication
- ThreatFrontier coverage, Oct. 2, 2026
- MITRE CWE-303: Incorrect Implementation of Authentication Algorithm
- MITRE CWE-862: Missing Authorization