CVE-2026-77244: [mcp-atlassian] Authentication bypass in HTTP transport: AtlassianOpaqueTokenVerifier accepts any non-empty token

Published Sep 22, 2026
·
Updated

Description

mcp-atlassian deploys in two common patterns:

Pattern A (single-user, server-side credentials): operator sets JIRAUSERNAME + JIRAAPITOKEN (or CONFLUENCEUSERNAME + CONFLUENCEAPITOKEN) in environment variables. Server uses these to call Jira/Confluence. This is the documented quickstart pattern.

Pattern B (multi-user, OAuth or per-request PAT): operator sets up OAuth proxy or accepts per-user tokens via Authorization or service headers.

The authentication mechanism in HTTP transport has two issues that combine to permit unauthenticated access to Pattern A deployments:

1. AtlassianOpaqueTokenVerifier.verifytoken() at src/mcpatlassian/utils/tokenverifier.py accepts any non-empty string as a valid token:

async def verifytoken(self, token: str) -> AccessToken | None: if not token: return None scopes = self.requiredscopes or [] return AccessToken( token=token, clientid="atlassian", scopes=scopes, expiresat=int(time.time()) + 86400 30, )

The docstring documents this: "we accept non-empty tokens and attach the required scopes."

2. The default deployment does NOT enable the OAuth proxy auth provider (OAUTHPROXYENABLEENV defaults to false; main.py:726). When buildauthprovider() returns None, FastMCP HTTP transport accepts requests with no authentication challenge.

3. UserTokenMiddleware.parseauthheader (main.py:601-664) extracts tokens from Authorization headers and stores them in scope state. If NO Authorization header is present (main.py:584-595), the middleware does not reject the request — it simply does not populate useratlassiantoken.

4. JiraFetcher / ConfluenceFetcher fall back to JiraConfig.fromenv() when no user-supplied token is in scope state. fromenv() reads JIRAAPITOKEN and JIRAUSERNAME from environment and uses them as the API credentials.

Composition: an attacker who reaches the HTTP transport (e.g., server exposed on a port reachable from attacker — direct bind, Docker port mapping, reverse proxy without auth, container in a network the attacker joined) can:

- Send no Authorization header at all, OR - Send any garbage Bearer token

Either request reaches tool handlers. The tool handlers, finding no user-supplied token, use the server's env-var credentials to call Jira / Confluence. The attacker has full operator-level access to the operator's Atlassian instance.

This is the same vulnerability class as CVE-2026-27825 (Arctic Wolf, unauthenticated RCE+SSRF in Atlassian MCP). The previous CVE was for a different code path; this report concerns the auth verifier and middleware behavior present in the current main branch. Steps to Reproduce

Source-level demonstration:

1. Verify the verifier accepts arbitrary tokens:

cd src/ python -c " import asyncio from mcpatlassian.utils.tokenverifier import AtlassianOpaqueTokenVerifier v = AtlassianOpaqueTokenVerifier(requiredscopes=['read:jira-work']) result = asyncio.run(v.verifytoken('anything-at-all')) print('Accepted:', result is not None) print('Token stored:', result.token if result else None) print('Scopes granted:', result.scopes if result else None) "

Expected: Accepted: True Token stored: anything-at-all Scopes granted: ['read:jira-work']

End-to-end (researcher's own Atlassian sandbox):

1. Start mcp-atlassian in HTTP mode against a researcher-owned Atlassian Cloud instance with JIRAAPITOKEN configured:

export JIRAURL=https://researcher.atlassian.net export JIRAUSERNAME=researcher@example.com export JIRAAPITOKEN=<researcher's-real-token> export MCPTRANSPORT=streamable-http export PORT=3000 # Do NOT set OAUTHPROXYENABLEENV — leave it default (false) mcp-atlassian

2. From another machine (or curl on localhost), with no auth:

curl -X POST http://localhost:3000/mcp \ -H "content-type: application/json" \ -H "accept: application/json, text/event-stream" \ -d '{ "jsonrpc":"2.0", "id":1, "method":"tools/call", "params":{ "name":"jiragetissue", "arguments":{"issuekey":"PROJ-1"} } }'

Expected: returns the Jira issue payload — using the server's JIRAAPITOKEN to authenticate to Atlassian. No client-side token provided.

3. Optional: same call with a garbage Bearer for completeness:

curl ... -H "Authorization: Bearer anything-at-all" ...

Same result. Impact: Attacker profile: any party with network reach to the HTTP transport. No credentials, no prior account, no privileged position required.

Typical deployment patterns at risk:

- Docker compose with port exposed (very common in mcp-atlassian's docs and community deployments) - Cloud-deployed MCP server behind a load balancer where the LB doesn't enforce auth (delegates to the application) - Internal corporate network where any employee can reach the server - Misconfigured Kubernetes ingress - Tunneled MCP server via ngrok / Cloudflare Tunnel for development that gets left exposed

Security impact after exploitation:

1. Full Jira read access. Every project, every issue, every comment, every attachment, every user — using the operator's API token.

2. Full Jira write access. Create, edit, delete issues. Add comments under the operator's identity. Move issues across boards. Bulk-edit.

3. Full Confluence read/write access. Same surface — pages, spaces, attachments, permissions, restricted spaces visible to the operator's identity.

4. Audit trail names the operator. Every API call is signed with the operator's token. From Atlassian's logging side, the operator is the actor — covering the attacker's tracks and shifting blame.

5. Pivot. Attachments often contain credentials, infrastructure diagrams, customer data. Confluence pages often store secrets in plaintext under the assumption of access control.

6. Persistence. Attacker can create new Jira webhooks, automation rules, or Confluence integrations that survive beyond the MCP session.

CVE-2026-27825 (Arctic Wolf, May 2026) was scored CVSS 9.8 Critical for unauth RCE+SSRF in this same code surface. This report is the auth-bypass component of the same class against the current main branch.

Suggested Fix

The most direct fix is the standard MCP-server-with-env-creds pattern:

1. When OAUTHPROXYENABLEENV is not set, REFUSE to start the HTTP transport unless an explicit "single-user mode" flag is set:

SINGLEUSERMODE = isenvtruthy("MCPATLASSIANSINGLEUSER") if MCPTRANSPORT == "streamable-http" and not authprovider and not SINGLEUSERMODE: raise SystemExit( "HTTP transport requires either OAUTHPROXYENABLE=true " "or MCPATLASSIANSINGLEUSER=true (acknowledges that env " "credentials will be used for any incoming request)." )

2. Even with SINGLEUSERMODE, bind the HTTP transport to 127.0.0.1 by default unless the operator overrides with an explicit MCPATLASSIANBINDPUBLIC=true.

3. Document the multi-tenant pattern as requiring OAuth proxy or per-request user-token middleware with a verifier that actually verifies (not the opaque-accept-anything stub).

4. Replace AtlassianOpaqueTokenVerifier with a verifier that performs a token-info or whoami call to Atlassian. The fact that Atlassian tokens are opaque does not preclude verification — a /rest/api/3/myself call validates the token and returns the associated user, which the verifier can attach to the AccessToken's scopes and userid fields.

Defense in depth: the README quickstart should not encourage exposing the HTTP transport without auth. The docker-compose.yml in the repo should bind to 127.0.0.1 only by default.

Other sources

MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, the HTTP transport accepts requests without a verified user identity and downstream fetcher construction falls back to the operator's globally configured Jira or Confluence credentials. A network client that can reach the MCP endpoint can invoke Atlassian tools as the operator, including read and write operations available to that account. The advisory traces the vulnerable input and processing flow through UserTokenMiddleware, AtlassianOpaqueTokenVerifier, getfetcher, and streamable-http, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.

MITRE

Affected Software

2 affected componentsFixes available
pypi/mcp-atlassian<0.22.0
pip/mcp-atlassian<0.22.0
0.22.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/mcp-atlassian to a version that resolves this vulnerability.

    Fixed in 0.22.0
  2. Upgrade

    Upgrade mcp-atlassian to a version that resolves this vulnerability.

    Fixed in 0.22.0
  3. Configuration

    Configure the HTTP transport to use the OAuth proxy by setting OAUTH_PROXY_ENABLE=true, or explicitly enable single-user mode with MCP_ATLASSIAN_SINGLE_USER=true when using server-side credentials.

    mcp-atlassian HTTP transport authentication mode = OAUTH_PROXY_ENABLE=true or MCP_ATLASSIAN_SINGLE_USER=true
  4. Configuration

    Bind the HTTP transport to 127.0.0.1 only, especially when MCP_ATLASSIAN_SINGLE_USER=true.

    mcp-atlassian HTTP transport bind address = 127.0.0.1

Event History

Sep 22, 2026
CVE Published
via MITRE·05:49 PM
Data Sourced
via MITRE·05:49 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·06:17 PM
DescriptionSeverityWeakness
Advisory Published
via GitHub·08:36 PM
Data Sourced
via GitHub·08:36 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Who is exposed to this issue?

Deployments of mcp-atlassian prior to 0.22.0 that expose the HTTP transport to reachable network clients are affected. Impact depends on the Jira or Confluence permissions held by the operator credentials configured globally for the server.

2

What does an attacker need to exploit it?

An attacker only needs network access to the MCP HTTP endpoint and a non-empty token. No verified user identity, prior privileges, or user interaction is required.

3

What can an attacker do after exploiting the bypass?

The attacker can invoke Atlassian tools using the server operator's globally configured Jira or Confluence credentials. This includes the read and write operations available to that account.

4

How can I remediate the issue?

Upgrade mcp-atlassian to version 0.22.0, which fixes the issue. If upgrading cannot happen immediately, restrict network access to the HTTP MCP endpoint to trusted clients because any reachable client can exploit the affected flow.

5

How can I identify the affected request path in my deployment?

The advisory identifies the affected HTTP processing path as UserTokenMiddleware, AtlassianOpaqueTokenVerifier, _get_fetcher, and streamable-http. Review whether your HTTP transport follows this path and is configured with global Jira or Confluence operator credentials.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203