CVE-2026-77246
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.
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
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 High
CVSS: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 High
CVSS: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 High
CVSS: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 High
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N - CVSS 3.1
- 8.6 High
CVSS: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 High
CVSS: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 High
CVSS: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 High
CVSS: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
| Package | Affected | Fixed |
|---|---|---|
mcp-atlassianPyPI |
before 0.22.0 | 0.22.0 |
mcp-atlassianPyPI |
before 0.22.0, plus listed versions 0.1.10.1.100.1.110.1.120.1.13 Show 45 moreShow less0.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
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE 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
github.com/sooperset/mcp-atlassian/security/advisories/GHSA-wv8v-v4c5-v75j
github.com/sooperset/mcp-atlassian/pull/1448
github.com/sooperset/mcp-atlassian/commit/b041733473f95119dd539542a43c280737a8e460
github.com/sooperset/mcp-atlassian/releases/tag/v0.22.0
github.com/advisories/GHSA-wv8v-v4c5-v75j
github.com/CVEProject/cvelistV5/tree/main/cves/2026/77xxx/CVE-2026-77246.json
nvd.nist.gov/vuln/detail/CVE-2026-77246
github.com/sooperset/mcp-atlassian
pypi.org/project/mcp-atlassian
Left out here: 29 versions and the rest of 3 source descriptions. The JSON record has them.