mcp-atlassian Path Traversal via confluence_upload_attachment (CVE-2026-27825)
by romain-deperne · 2026-07-05
- Severity
- Critical
- CVE
- CVE-2026-27825 (read-side twin of GHSA-xjgw-4wvw-rgm4)
- Category
- web
- Affected product
- sooperset/mcp-atlassian MCP server
- Affected versions
- >= 0.17.0
- Disclosed
- 2026-07-05
- Patch status
- unpatched
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-04 |
| Author / Researcher | romain-deperne |
| CVE / Advisory | CVE-2026-27825 (read-side twin of GHSA-xjgw-4wvw-rgm4) |
| Category | web |
| Severity | Critical |
| CVSS Score | 9.3 |
| Status | PoC |
| Tags | mcp, path-traversal, arbitrary-file-read, confluence, mcp-atlassian, cwe-22, unauthenticated |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | sooperset/mcp-atlassian MCP server |
| Versions Affected | >= 0.17.0 |
| Language / Platform | Python (MCP stdio/streamable-http server) |
| Authentication Required | No |
| Network Access Required | Yes |
Summary
The confluence_upload_attachment MCP tool in mcp-atlassian passes its file_path argument straight into open(file_path, "rb") with no path validation, letting an attacker read arbitrary files on the server’s filesystem and exfiltrate them via a multipart upload to an attacker-controlled Confluence endpoint. This is the mirror-image flaw to a previously patched download-path traversal (GHSA-xjgw-4wvw-rgm4): the v0.17.0 fix added validate_safe_path() on the write/download path but never applied the same guard to the upload/read path. Because the default streamable-http transport binds to 0.0.0.0 with no authentication layer, any network-reachable client can invoke the MCP tool directly. The PoC spawns the real mcp-atlassian server, drives it with an MCP client session, and points file_path at /etc/passwd against a local mock Confluence HTTP stub, confirming the file contents are exfiltrated in the upload body.
Vulnerability Details
Root Cause
src/mcp_atlassian/confluence/attachments.py:477 calls open(file_path, "rb") on the attacker-controlled file_path argument with no call to validate_safe_path(), unlike the patched download path at lines 223/272 in the same file.
Attack Vector
- Connect to the target mcp-atlassian server’s default
streamable-httpendpoint (bound0.0.0.0, no auth). - Invoke the
confluence_upload_attachmentMCP tool withfile_pathset to an absolute path outside the intended attachment directory (e.g./etc/passwd). - The server opens and reads the specified file and uploads its contents via multipart POST to the configured Confluence URL.
- Point the Confluence URL at an attacker-controlled endpoint (or intercept the mock/real Confluence traffic) to capture the exfiltrated file contents.
Impact
Unauthenticated arbitrary file read and exfiltration of any file readable by the mcp-atlassian process, including credentials, SSH keys, and .env/application secrets.
Environment / Lab Setup
Target: sooperset/mcp-atlassian >= 0.17.0, default streamable-http transport (0.0.0.0, no auth)
Attacker: Python 3 with the `mcp` client library, local mock Confluence HTTP stub (mock_confluence.py)
Proof of Concept
PoC Script
See
mcp_client.py,mock_confluence.py, andpoc_run1.shin this folder.
| |
poc_run1.sh orchestrates both steps: it starts the mock Confluence server, then drives the real mcp-atlassian server via mcp_client.py to upload /etc/passwd, and the mock server’s log shows the full file contents arriving in the multipart body.
Detection & Indicators of Compromise
Signs of compromise:
confluence_upload_attachmentMCP tool invocations withfile_pathvalues pointing outside expected attachment directories (absolute paths,../sequences)- Unexpected outbound multipart uploads from the mcp-atlassian host to unfamiliar Confluence/attacker endpoints
- MCP server logs showing tool calls from unauthenticated/unexpected clients (default
0.0.0.0binding)
Remediation
| Action | Detail |
|---|---|
| Primary fix | No vendor patch confirmed as of 2026-07-05 — apply validate_safe_path() to the upload path in attachments.py:477, mirroring the existing download-path guard |
| Interim mitigation | Do not expose mcp-atlassian’s streamable-http transport on 0.0.0.0; bind to localhost or place behind an authenticating reverse proxy, and restrict which paths the tool can read |
References
Notes
Mirrored from https://github.com/romain-deperne/CVE-2026-27825 on 2026-07-05.
| |