CVE-2026-77244 (CVSS 10.0): mcp-atlassian's HTTP transport ran unauthenticated requests with the operator's Atlassian token. Upgrade to 0.23.1.
Anyone who could reach an mcp-atlassian server running over HTTP could use Jira and Confluence as the person who deployed it. They needed no account, no token and no user interaction. The flaw, CVE-2026-77244, is rated CVSS 10.0 by GitHub, the CNA, and NVD published it on 22 September 2026.
mcp-atlassian is the community Model Context Protocol (MCP) server that lets AI assistants and agents read and write Jira issues and Confluence pages. The project has nearly 6,000 GitHub stars, and pypistats counted 699,442 PyPI downloads of the package in the last 30 days. It is not an Atlassian product. It is maintained in the sooperset/mcp-atlassian repository and is a common way to connect Claude, Cursor and other MCP clients to an Atlassian tenant.
The fix shipped in version 0.22.0 on 10 July 2026, 74 days before the NVD record appeared. The advisory GHSA-wrhw-j3f9-8vc6 went live the same day. Anyone who updated over the summer is covered for this CVE. Anyone who pinned an older release, or runs a container image built before July, is not. A related bypass in the SSE transport stayed open until 0.23.1 on 19 August, so that is the version to run.
What went wrong
The advisory, credited to GitHub user crazydude123, describes two deployment patterns. In the multi-user pattern, each client brings its own Atlassian token through an OAuth proxy or a per-request header. In the single-user pattern, which the advisory calls the documented quickstart, the operator puts JIRA_USERNAME and JIRA_API_TOKEN (or the Confluence equivalents) in environment variables and the server uses them for every call.
Over the HTTP transport, four pieces of behaviour combined into a full bypass:
- The token verifier accepted anything.
AtlassianOpaqueTokenVerifier.verify_token()returned a valid access token for any non-empty string, with the required scopes attached. Its own docstring said so. - No auth provider by default. The OAuth proxy is off unless the operator turns it on, and with no provider FastMCP's HTTP transport does not challenge requests.
- The middleware did not reject missing headers.
UserTokenMiddlewareparsed anAuthorizationheader when one was present. When it was absent, the request went through with no user token attached. - The fetchers fell back to the operator. When
_get_fetcherfound no user token, it built the Jira or Confluence client from the environment, that is, from the operator's own credentials.
The result: a request with no Authorization header, or with Bearer anything-at-all, reached the tool handlers and ran as the operator. The advisory's proof of concept is a single unauthenticated curl POST of a tools/call for jira_get_issue to the /mcp endpoint, which returns the issue.
How a request with no credentials reached Jira and Confluence as the operator before 0.22.0. Source: GHSA-wrhw-j3f9-8vc6.
What an attacker gets
Everything the operator's Atlassian account can do, through every enabled tool. The advisory lists:
- read access to every Jira project, issue, comment and attachment, and every Confluence space and page the account can see
- write access: creating, editing and deleting issues and pages, and commenting in the operator's name
- an audit trail that names the operator, since every API call is signed with the operator's token
- a pivot into whatever teams keep in tickets and wiki pages: credentials, infrastructure diagrams, customer data
- persistence through new webhooks, automation rules or integrations that outlive the MCP session
The exposure paths it names are ordinary: a Docker port mapping, a load balancer that leaves auth to the app, an internal network any employee can reach, a Kubernetes ingress, or a development tunnel through ngrok or Cloudflare Tunnel left running. GitHub scored it network, low complexity, no privileges, no user interaction, scope changed, with high confidentiality and integrity impact. The weaknesses are CWE-287, CWE-303 and CWE-862. CISA's SSVC entry marks it automatable with total technical impact, and records no known exploitation.
One of 33
CVE-2026-77244 was not fixed alone. The 0.22.0 release notes describe a security audit of 37 advisories consolidated into root-cause families, and the repository's advisory list shows 33 published on 10 July: 2 critical, 19 high and 12 medium. NVD published their CVE records on 22 September.
They cluster into a few families:
- Transport authentication. CVE-2026-77244 and CVE-2026-77254 (GHSA-vc8m-84rp-53hx, CVSS 9.1) both describe unauthenticated HTTP requests running with the global credentials. CVE-2026-77248 (GHSA-cc5h-2pwp-pvcc) chains an unauthenticated file read through
upload_attachment. - Attachment path confinement. More than a dozen reports of upload and download tools reading arbitrary server-local files and attaching them to Jira or Confluence, plus an intra-directory overwrite that led to code execution (CVE-2026-77271).
- SSRF. DNS-rebinding and redirect bypasses of the fix for February's CVE-2026-27826.
- Policy bypasses.
ENABLED_TOOLSand read-only mode could be skipped by calling a hidden tool by name (CVE-2026-77243), and the project and space filters could be widened. - Hygiene. OAuth token files written group- or world-readable, and a reflected XSS in the OAuth callback.
These came after February's CVE-2026-27825, an arbitrary file write leading to code execution through download_path, and CVE-2026-27826, the header-based SSRF.
What 0.22.0 changed, and what it missed
Version 0.22.0 rejects unauthenticated streamable-HTTP requests with a 401 at the transport boundary. Falling back to the operator's credentials is now opt-in through ALLOW_GLOBAL_CRED_FALLBACK, which is off by default and documented for single-user deployments only.
That boundary check only covered the /mcp path. GHSA-5j8j-256g-vvp5, published on 19 August with a CVSS 10.0 score from GitHub and no CVE id yet, showed that under --transport sse the middleware never matched the real /sse and /messages/ paths. It skipped authentication entirely and dropped even valid headers. Because SSE clients then could not authenticate, operators who wanted SSE to work turned on ALLOW_GLOBAL_CRED_FALLBACK, and every anonymous request ran as the operator again. Versions up to 0.23.0 are affected. 0.23.1 makes the SSE endpoints enforce the same per-request authentication.
mcp-atlassian fixed CVE-2026-77244 in July; NVD published it in September, and the SSE transport needed 0.23.1. Sources: GitHub advisories and releases, NVD.
What to do
- Upgrade to 0.23.1 or later. 0.22.0 closes CVE-2026-77244 and its siblings. 0.23.1 closes the SSE path.
- Find every instance. Check Python environments,
uvxcaches and container images formcp-atlassian, including desktop setups that run it over HTTP for several clients. - Leave
ALLOW_GLOBAL_CRED_FALLBACKoff on anything more than one person can reach. If it must be on, bind to127.0.0.1and put real authentication in front. - Do not expose the port. The advisory's exposure list (Docker port mappings, ingresses, tunnels) is the place to start looking.
- Review the operator account's activity. Unexpected issue or page edits, new webhooks, new automation rules and new integrations created by the service account since the server went up are the signs to look for.
- Rotate the token if an older version was ever reachable from a network you do not fully control, and scope the replacement to the projects and spaces the agent actually needs.
The broader lesson is the one we covered in zero-trust MCP and the agent control plane. An MCP server that holds one service credential and serves many callers is an authorization boundary. If it does not check who is calling, the tools do whatever that credential allows.