Every CVE Search/ Get API key

CVE-2026-77246

MCP Atlassian: MCP HTTP Client Server-Local File Exfiltration via Unvalidated Attachment Upload Path

7.4 HighFix available

MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, an HTTP transport deployment with READ_ONLY_MODE=false accepts a request without an Authorization identity and permits attacker-controlled Atlassian service headers, including X-Atlassian-Confluence-Url, to select a public attacker hostname or one allowed by MCP_ALLOWED_URL_DOMAINS. A caller can then invoke confluence_upload_attachment or the Jira attachment variant in src/mcp_atlassian/jira/attachments.py with a server-local file_path and cause the MCP process to send the file to the selected attachment endpoint. This issue is fixed in version 0.22.0.

Attack profile

How easy it is to exploit

Attack vector
Adjacent network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
None
Availability
None

Exploit likelihood

0.47%Up 0.2 points since Sep 23, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.4

MCP Atlassian: MCP HTTP Client Server-Local File Exfiltration via Unvalidated Attachment Upload Path

MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, an HTTP transport deployment with READ_ONLY_MODE=false accepts a request without an Authorization identity and permits attacker-controlled Atlassian service headers, including X-Atlassian-Confluence-Url, to select a public attacker hostname or one allowed by MCP_ALLOWED_URL_DOMAINS. A caller can then invoke confluence_upload_attachment or the Jira attachment variant in src/mcp_atlassian/jira/attachments.py with a server-local file_path and cause the MCP process to send the file to the selected attachment endpoint. This issue is fixed in version 0.22.0.

Record
CVE-2026-77246
CVSS 3.1
7.4 HighCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-22, CWE-200, CWE-441
Updated
2026-11-02
EUVDEUVD-2026-84771 7.4

MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, an HTTP transport deployment with READ_ONLY_MODE=false accepts a request without an Authorization identity and permits attacker-controlled Atlassian service headers, including X-Atlassian-Confluence-Url, to select a public attacker hostname or one allowed by MCP_ALLOWED_URL_DOMAINS. A caller can then invoke confluence_upload_attachment or the Jira attachment variant in src/mcp_atlassian/jira/attachments.py with a server-local file_path and cause the MCP process to send the file to the selected attachment endpoint. This issue is fixed in version 0.22.0.

Record
EUVD-2026-84771
CVSS 3.1
7.4 HighCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-wv8v-v4c5-v75j 7.4

MCP Atlassian: MCP HTTP Client Server-Local File Exfiltration via Unvalidated Attachment Upload Path

Summary

The mcp-atlassian server exposes an MCP tool (confluence_upload_attachment and the Jira attachment variant) that accepts an arbitrary server-side file path and opens it for upload without any path validation. When the server is deployed in HTTP transport mode (streamable-http or sse), a remote, unauthenticated attacker can supply attacker-controlled Atlassian service headers (X-Atlassian-Confluence-Url / X-Atlassian-Confluence-Personal-Token) to redirect the upload to an attacker-controlled endpoint, then pass an arbitrary file_path (e.g. /etc/passwd, ~/.env, SSH private keys, cloud credentials) to exfiltrate any file readable by the server process. No prior account, session token, or Authorization header is required. The vulnerability was confirmed through both static code analysis (Phase 1) and a live Docker-based proof-of-concept (Phase 2).


Details

Data flow (source → sink)

| Step | Location | Role | |------|----------|------| | 1 | src/mcp_atlassian/servers/main.py:498-504 | Middleware extracts X-Atlassian-Confluence-Url and X-Atlassian-Confluence-Personal-Token from incoming HTTP request headers. | | 2 | src/mcp_atlassian/servers/main.py:584-595 | When no Authorization header is present but service headers are, user_atlassian_auth_type is set to "pat", effectively bypassing authentication requirements. | | 3 | src/mcp_atlassian/utils/urls.py:97-104 | validate_url_for_ssrf blocks only localhost, RFC 1918 private ranges, and a small set of metadata hostnames. An attacker-controlled public domain or an allow-listed Docker container hostname (MCP_ALLOWED_URL_DOMAINS) passes this check. | | 4 | src/mcp_atlassian/servers/dependencies.py:544-545 | The attacker-controlled URL is injected directly as url= into ConfluenceConfig, constructing a ConfluenceFetcher pointed at the attacker's server. | | 5 | src/mcp_atlassian/servers/confluence.py:1358-1361 | The MCP tool argument file_path is forwarded to confluence_fetcher.upload_attachment() without any sanitization. | | 6 | src/mcp_atlassian/confluence/attachments.py:64-79 | The path is converted to an absolute path via os.path.abspath() and checked for existence only. validate_safe_path() — already used on download paths — is never called here, leaving no directory restriction in place. | | 7 | src/mcp_atlassian/confluence/attachments.py:477 | Sink: files = {"file": (filename, open(file_path, "rb"))} — the file is opened and sent as multipart to the attacker's server. | | 8 | src/mcp_atlassian/jira/attachments.py:374-386 | Parallel Jira sink: same os.path.abspath() pattern, no validate_safe_path, then open(file_path, "rb"). |

Key code evidence

# src/mcp_atlassian/confluence/attachments.py
64: if not os.path.isabs(file_path):
65:     file_path = os.path.abspath(file_path)
68: if not os.path.exists(file_path):
77: filename = os.path.basename(file_path)
477: files = {"file": (filename, open(file_path, "rb"))}   # ← sink
# src/mcp_atlassian/jira/attachments.py
374: if not os.path.isabs(file_path):
375:     file_path = os.path.abspath(file_path)
386: with open(file_path, "rb") as file:                    # ← sink
387:     attachment = self.jira.add_attachment(

Why validate_safe_path is absent: The function exists in the codebase and is correctly applied to download/read operations, but it was not applied to the upload path. This asymmetry means an attacker can read any file the server process can access, even though the intent was clearly to restrict path access.

Default configuration enables the attack: READ_ONLY_MODE defaults to false, making write tools (including attachment upload) active by default. HTTP transport is a first-class, documented production deployment mode (README, Helm chart, multi-tenant header-auth design).

Recommended remediation

--- a/src/mcp_atlassian/confluence/attachments.py…
Record
GHSA-wv8v-v4c5-v75j
CVSS 3.1
7.4 HighCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-22, CWE-200, CWE-441
Updated
2026-11-02
NVD 7.4

MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, an HTTP transport deployment with READ_ONLY_MODE=false accepts a request without an Authorization identity and permits attacker-controlled Atlassian service headers, including X-Atlassian-Confluence-Url, to select a public attacker hostname or one allowed by MCP_ALLOWED_URL_DOMAINS. A caller can then invoke confluence_upload_attachment or the Jira attachment variant in src/mcp_atlassian/jira/attachments.py with a server-local file_path and cause the MCP process to send the file to the selected attachment endpoint. This issue is fixed in version 0.22.0.

Record
CVE-2026-77246
CVSS 3.1
7.4 HighCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
CVSS 3.1
8.6 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-22, CWE-200, CWE-441
Updated
2026-11-02
OSV 7.4

MCP Atlassian: MCP HTTP Client Server-Local File Exfiltration via Unvalidated Attachment Upload Path

MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, an HTTP transport deployment with READ_ONLY_MODE=false accepts a request without an Authorization identity and permits attacker-controlled Atlassian service headers, including X-Atlassian-Confluence-Url, to select a public attacker hostname or one allowed by MCP_ALLOWED_URL_DOMAINS. A caller can then invoke confluence_upload_attachment or the Jira attachment variant in src/mcp_atlassian/jira/attachments.py with a server-local file_path and cause the MCP process to send the file to the selected attachment endpoint. This issue is fixed in version 0.22.0.

Record
CVE-2026-77246
CVSS 3.1
7.4 HighCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-200, CWE-22, CWE-441
Updated
2026-11-02
OSVGHSA-wv8v-v4c5-v75j 7.4

MCP Atlassian: MCP HTTP Client Server-Local File Exfiltration via Unvalidated Attachment Upload Path

Summary

The mcp-atlassian server exposes an MCP tool (confluence_upload_attachment and the Jira attachment variant) that accepts an arbitrary server-side file path and opens it for upload without any path validation. When the server is deployed in HTTP transport mode (streamable-http or sse), a remote, unauthenticated attacker can supply attacker-controlled Atlassian service headers (X-Atlassian-Confluence-Url / X-Atlassian-Confluence-Personal-Token) to redirect the upload to an attacker-controlled endpoint, then pass an arbitrary file_path (e.g. /etc/passwd, ~/.env, SSH private keys, cloud credentials) to exfiltrate any file readable by the server process. No prior account, session token, or Authorization header is required. The vulnerability was confirmed through both static code analysis (Phase 1) and a live Docker-based proof-of-concept (Phase 2).


Details

Data flow (source → sink)

| Step | Location | Role | |------|----------|------| | 1 | src/mcp_atlassian/servers/main.py:498-504 | Middleware extracts X-Atlassian-Confluence-Url and X-Atlassian-Confluence-Personal-Token from incoming HTTP request headers. | | 2 | src/mcp_atlassian/servers/main.py:584-595 | When no Authorization header is present but service headers are, user_atlassian_auth_type is set to "pat", effectively bypassing authentication requirements. | | 3 | src/mcp_atlassian/utils/urls.py:97-104 | validate_url_for_ssrf blocks only localhost, RFC 1918 private ranges, and a small set of metadata hostnames. An attacker-controlled public domain or an allow-listed Docker container hostname (MCP_ALLOWED_URL_DOMAINS) passes this check. | | 4 | src/mcp_atlassian/servers/dependencies.py:544-545 | The attacker-controlled URL is injected directly as url= into ConfluenceConfig, constructing a ConfluenceFetcher pointed at the attacker's server. | | 5 | src/mcp_atlassian/servers/confluence.py:1358-1361 | The MCP tool argument file_path is forwarded to confluence_fetcher.upload_attachment() without any sanitization. | | 6 | src/mcp_atlassian/confluence/attachments.py:64-79 | The path is converted to an absolute path via os.path.abspath() and checked for existence only. validate_safe_path() — already used on download paths — is never called here, leaving no directory restriction in place. | | 7 | src/mcp_atlassian/confluence/attachments.py:477 | Sink: files = {"file": (filename, open(file_path, "rb"))} — the file is opened and sent as multipart to the attacker's server. | | 8 | src/mcp_atlassian/jira/attachments.py:374-386 | Parallel Jira sink: same os.path.abspath() pattern, no validate_safe_path, then open(file_path, "rb"). |

Key code evidence

# src/mcp_atlassian/confluence/attachments.py
64: if not os.path.isabs(file_path):
65:     file_path = os.path.abspath(file_path)
68: if not os.path.exists(file_path):
77: filename = os.path.basename(file_path)
477: files = {"file": (filename, open(file_path, "rb"))}   # ← sink
# src/mcp_atlassian/jira/attachments.py
374: if not os.path.isabs(file_path):
375:     file_path = os.path.abspath(file_path)
386: with open(file_path, "rb") as file:                    # ← sink
387:     attachment = self.jira.add_attachment(

Why validate_safe_path is absent: The function exists in the codebase and is correctly applied to download/read operations, but it was not applied to the upload path. This asymmetry means an attacker can read any file the server process can access, even though the intent was clearly to restrict path access.

Default configuration enables the attack: READ_ONLY_MODE defaults to false, making write tools (including attachment upload) active by default. HTTP transport is a first-class, documented production deployment mode (README, Helm chart, multi-tenant header-auth design).

Recommended remediation

--- a/src/mcp_atlassian/confluence/attachments.py…
Record
GHSA-wv8v-v4c5-v75j
CVSS 3.1
7.4 HighCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-200, CWE-22, CWE-441
Updated
2026-11-02
OSVPYSEC-2026-4104 7.4

MCP Atlassian: MCP HTTP Client Server-Local File Exfiltration via Unvalidated Attachment Upload Path

Summary

The mcp-atlassian server exposes an MCP tool (confluence_upload_attachment and the Jira attachment variant) that accepts an arbitrary server-side file path and opens it for upload without any path validation. When the server is deployed in HTTP transport mode (streamable-http or sse), a remote, unauthenticated attacker can supply attacker-controlled Atlassian service headers (X-Atlassian-Confluence-Url / X-Atlassian-Confluence-Personal-Token) to redirect the upload to an attacker-controlled endpoint, then pass an arbitrary file_path (e.g. /etc/passwd, ~/.env, SSH private keys, cloud credentials) to exfiltrate any file readable by the server process. No prior account, session token, or Authorization header is required. The vulnerability was confirmed through both static code analysis (Phase 1) and a live Docker-based proof-of-concept (Phase 2).


Details

Data flow (source → sink)

| Step | Location | Role | |------|----------|------| | 1 | src/mcp_atlassian/servers/main.py:498-504 | Middleware extracts X-Atlassian-Confluence-Url and X-Atlassian-Confluence-Personal-Token from incoming HTTP request headers. | | 2 | src/mcp_atlassian/servers/main.py:584-595 | When no Authorization header is present but service headers are, user_atlassian_auth_type is set to "pat", effectively bypassing authentication requirements. | | 3 | src/mcp_atlassian/utils/urls.py:97-104 | validate_url_for_ssrf blocks only localhost, RFC 1918 private ranges, and a small set of metadata hostnames. An attacker-controlled public domain or an allow-listed Docker container hostname (MCP_ALLOWED_URL_DOMAINS) passes this check. | | 4 | src/mcp_atlassian/servers/dependencies.py:544-545 | The attacker-controlled URL is injected directly as url= into ConfluenceConfig, constructing a ConfluenceFetcher pointed at the attacker's server. | | 5 | src/mcp_atlassian/servers/confluence.py:1358-1361 | The MCP tool argument file_path is forwarded to confluence_fetcher.upload_attachment() without any sanitization. | | 6 | src/mcp_atlassian/confluence/attachments.py:64-79 | The path is converted to an absolute path via os.path.abspath() and checked for existence only. validate_safe_path() — already used on download paths — is never called here, leaving no directory restriction in place. | | 7 | src/mcp_atlassian/confluence/attachments.py:477 | Sink: files = {"file": (filename, open(file_path, "rb"))} — the file is opened and sent as multipart to the attacker's server. | | 8 | src/mcp_atlassian/jira/attachments.py:374-386 | Parallel Jira sink: same os.path.abspath() pattern, no validate_safe_path, then open(file_path, "rb"). |

Key code evidence

# src/mcp_atlassian/confluence/attachments.py
64: if not os.path.isabs(file_path):
65:     file_path = os.path.abspath(file_path)
68: if not os.path.exists(file_path):
77: filename = os.path.basename(file_path)
477: files = {"file": (filename, open(file_path, "rb"))}   # ← sink
# src/mcp_atlassian/jira/attachments.py
374: if not os.path.isabs(file_path):
375:     file_path = os.path.abspath(file_path)
386: with open(file_path, "rb") as file:                    # ← sink
387:     attachment = self.jira.add_attachment(

Why validate_safe_path is absent: The function exists in the codebase and is correctly applied to download/read operations, but it was not applied to the upload path. This asymmetry means an attacker can read any file the server process can access, even though the intent was clearly to restrict path access.

Default configuration enables the attack: READ_ONLY_MODE defaults to false, making write tools (including attachment upload) active by default. HTTP transport is a first-class, documented production deployment mode (README, Helm chart, multi-tenant header-auth design).

Recommended remediation

--- a/src/mcp_atlassian/confluence/attachments.py…
Record
PYSEC-2026-4104
CVSS 3.1
7.4 HighCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:N/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-77246 is a high vulnerability (CVSS 7.4) 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.47%, the 40th 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