Every CVE Search/ Get API key

CVE-2026-77244

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

10.0 CriticalFix available

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, _get_fetcher, and streamable-http, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Exploit likelihood

0.35%Down 0.1 points since Sep 23, 2026
90%50%10%1%

What each source reports

CVE List Score used 10.0

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

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, _get_fetcher, and streamable-http, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.

Record
CVE-2026-77244
CVSS 3.1
10.0 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-303, CWE-862
Updated
2026-11-02
EUVDEUVD-2026-84607 10.0

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, _get_fetcher, and streamable-http, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.

Record
EUVD-2026-84607
CVSS 3.1
10.0 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-wrhw-j3f9-8vc6 10.0

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

Description

mcp-atlassian deploys in two common patterns:

Pattern A (single-user, server-side credentials): operator sets JIRA_USERNAME + JIRA_API_TOKEN (or CONFLUENCE_USERNAME + CONFLUENCE_API_TOKEN) 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.verify_token() at src/mcp_atlassian/utils/token_verifier.py accepts any non-empty string as a valid token:

    async def verify_token(self, token: str) -> AccessToken | None:
        if not token:
            return None
        scopes = self.required_scopes or []
        return AccessToken(
            token=token,
            client_id="atlassian",
            scopes=scopes,
            expires_at=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 (OAUTH_PROXY_ENABLE_ENV defaults to false; main.py:726). When _build_auth_provider() returns None, FastMCP HTTP transport accepts requests with no authentication challenge.

  3. UserTokenMiddleware._parse_auth_header (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 user_atlassian_token.

  4. JiraFetcher / ConfluenceFetcher fall back to JiraConfig.from_env() when no user-supplied token is in scope state. from_env() reads JIRA_API_TOKEN and JIRA_USERNAME 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 mcp_atlassian.utils.token_verifier import AtlassianOpaqueTokenVerifier
       v = AtlassianOpaqueTokenVerifier(required_scopes=['read:jira-work'])
       result = asyncio.run(v.verify_token('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 JIRA_API_TOKEN configured:

       export JIRA_URL=https://researcher.atlassian.net
       export [email protected]
       export JIRA_API_TOKEN=<researcher's-real-token>
       export MCP_TRANSPORT=streamable-http
       export PORT=3000
       # Do NOT set OAUTH_PROXY_ENABLE_ENV — leave it default…
Record
GHSA-wrhw-j3f9-8vc6
CVSS 3.1
10.0 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-303, CWE-862
Updated
2026-11-02
NVD 10.0

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, _get_fetcher, and streamable-http, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.

Record
CVE-2026-77244
CVSS 3.1
10.0 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-303, CWE-862
Updated
2026-11-02
OSV 10.0

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

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, _get_fetcher, and streamable-http, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.

Record
CVE-2026-77244
CVSS 3.1
10.0 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-303, CWE-862
Updated
2026-11-02
OSVGHSA-wrhw-j3f9-8vc6 10.0

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

Description

mcp-atlassian deploys in two common patterns:

Pattern A (single-user, server-side credentials): operator sets JIRA_USERNAME + JIRA_API_TOKEN (or CONFLUENCE_USERNAME + CONFLUENCE_API_TOKEN) 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.verify_token() at src/mcp_atlassian/utils/token_verifier.py accepts any non-empty string as a valid token:

    async def verify_token(self, token: str) -> AccessToken | None:
        if not token:
            return None
        scopes = self.required_scopes or []
        return AccessToken(
            token=token,
            client_id="atlassian",
            scopes=scopes,
            expires_at=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 (OAUTH_PROXY_ENABLE_ENV defaults to false; main.py:726). When _build_auth_provider() returns None, FastMCP HTTP transport accepts requests with no authentication challenge.

  3. UserTokenMiddleware._parse_auth_header (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 user_atlassian_token.

  4. JiraFetcher / ConfluenceFetcher fall back to JiraConfig.from_env() when no user-supplied token is in scope state. from_env() reads JIRA_API_TOKEN and JIRA_USERNAME 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 mcp_atlassian.utils.token_verifier import AtlassianOpaqueTokenVerifier
       v = AtlassianOpaqueTokenVerifier(required_scopes=['read:jira-work'])
       result = asyncio.run(v.verify_token('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 JIRA_API_TOKEN configured:

       export JIRA_URL=https://researcher.atlassian.net
       export [email protected]
       export JIRA_API_TOKEN=<researcher's-real-token>
       export MCP_TRANSPORT=streamable-http
       export PORT=3000
       # Do NOT set OAUTH_PROXY_ENABLE_ENV — leave it default…
Record
GHSA-wrhw-j3f9-8vc6
CVSS 3.1
10.0 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-287, CWE-303, CWE-862
Updated
2026-11-02
OSVPYSEC-2026-4103 10.0

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

Description

mcp-atlassian deploys in two common patterns:

Pattern A (single-user, server-side credentials): operator sets JIRA_USERNAME + JIRA_API_TOKEN (or CONFLUENCE_USERNAME + CONFLUENCE_API_TOKEN) 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.verify_token() at src/mcp_atlassian/utils/token_verifier.py accepts any non-empty string as a valid token:

    async def verify_token(self, token: str) -> AccessToken | None:
        if not token:
            return None
        scopes = self.required_scopes or []
        return AccessToken(
            token=token,
            client_id="atlassian",
            scopes=scopes,
            expires_at=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 (OAUTH_PROXY_ENABLE_ENV defaults to false; main.py:726). When _build_auth_provider() returns None, FastMCP HTTP transport accepts requests with no authentication challenge.

  3. UserTokenMiddleware._parse_auth_header (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 user_atlassian_token.

  4. JiraFetcher / ConfluenceFetcher fall back to JiraConfig.from_env() when no user-supplied token is in scope state. from_env() reads JIRA_API_TOKEN and JIRA_USERNAME 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 mcp_atlassian.utils.token_verifier import AtlassianOpaqueTokenVerifier
       v = AtlassianOpaqueTokenVerifier(required_scopes=['read:jira-work'])
       result = asyncio.run(v.verify_token('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 JIRA_API_TOKEN configured:

       export JIRA_URL=https://researcher.atlassian.net
       export [email protected]
       export JIRA_API_TOKEN=<researcher's-real-token>
       export MCP_TRANSPORT=streamable-http
       export PORT=3000
       # Do NOT set OAUTH_PROXY_ENABLE_ENV — leave it default…
Record
PYSEC-2026-4103
CVSS 3.1
10.0 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
mcp-atlassian
PyPI
before 0.22.0
0.22.0
mcp-atlassian
PyPI
before 0.22.0, plus listed versions
0.1.10.1.100.1.110.1.120.1.13
Show 45 moreShow less
0.1.140.1.150.1.160.1.20.1.30.1.40.1.60.1.70.1.80.1.90.10.00.10.10.10.20.10.30.10.40.10.50.10.60.11.00.11.10.11.100.11.110.11.120.11.20.11.2a20.11.30.11.40.11.50.11.60.11.70.11.80.11.90.12.00.13.00.13.10.14.00.14.10.14.20.14.30.15.00.16.00.16.10.17.00.18.00.18.10.19.0
0.22.0

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-77244 is a critical vulnerability (CVSS 10.0) in Mcp-atlassian Mcp Atlassian, published September 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.35%, the 28th percentile. Fixed in mcp-atlassian 0.22.0.

References

This page doesn't list everything

Left out here: 29 versions and the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open