NewApp Monitoring is liveSign up free
AgentbeamBeta
AI agent vulnerability · Other MCP servers and tools

CVE-2026-77248: MCP Atlassian: Unauthenticated arbitrary local file read via upload_attachment file_path, chained with missing auth on streamable-http transport

highCVSS 3.1 8.6GHSA-cc5h-2pwp-pvcc

On a default `--transport streamable-http` mcp-atlassian server, unauthenticated clients can call every tool, and `upload_attachment` reads any `file_path` on the server host. An attacker can upload `/proc/self/environ` to a page or issue and read it back, which exposes the operator's Atlassian API token and `.env` secrets. Versions up to 0.21.1 are affected; upgrade to 0.22.0.

Published Sep 22, 2026 · Analysis Oct 22, 2026

What an attacker can do

Two gaps combine. The streamable-http transport binds 0.0.0.0 by default (__init__.py). The OAuth-proxy provider is opt-in (ATLASSIAN_OAUTH_PROXY_ENABLE, off by default), so the server is built with auth=None. UserTokenMiddleware._parse_auth_header flags only a malformed Authorization header, and a request with none passes through. _get_fetcher in dependencies.py then falls back to the operator's global credentials from .env. check_write_access checks only read-only mode, so read and write tools are reachable.

The sink is upload_attachment: its file_path flows into open(file_path, 'rb') in confluence/attachments.py and jira/attachments.py with no validate_safe_path or allowlist, unlike the download flow. The proof of concept calls upload_attachment with /proc/self/environ and a page ID the attacker chooses, then reads the bytes back with download_attachment.

The result is unauthenticated arbitrary file read on the MCP server host, including ~/.ssh/id_rsa and /etc/passwd, plus unauthenticated use of every Atlassian tool as the operator, often an admin. The CVSS vector reflects network access with no privileges, a changed scope and high confidentiality impact.

Who is affected

mcp-atlassian up to and including 0.21.1 (the package data lists everything before 0.22.0) when run with --transport streamable-http and global operator Atlassian credentials, with the OAuth proxy not enabled. Anyone who can reach the port is a potential attacker.

pip show mcp-atlassian

Check whether the container publishes the port and whether ATLASSIAN_OAUTH_PROXY_ENABLE is set.

mcp-atlassian

Ecosystem
PyPI
Affected
< 0.22.0
Fixed in
0.22.0
Check
pip show mcp-atlassian

How to fix it

Upgrade to mcp-atlassian 0.22.0:

pip install -U mcp-atlassian==0.22.0

The fix is PR #1448. The report's suggested fix is to require authentication on the streamable-http transport by default, never fall back to the operator's global credentials for unauthenticated requests, and apply validate_safe_path or an allowlist to the upload file_path. The sources give no workaround. As stopgaps, enable the OAuth proxy, put authentication in front of the port, bind to 127.0.0.1, and set READ_ONLY_MODE=true. Rotate the Atlassian token and any .env secrets if the server was exposed.

How to tell if you were hit

Look in the MCP server logs for tools/call of upload_attachment with file_path values such as /proc/self/environ, /etc/passwd or key paths, followed by download_attachment calls, from clients that sent no Authorization header. In Jira and Confluence, review recent attachments added by the operator account for files that contain environment variables or keys, and delete them. Check Atlassian audit logs for activity by the operator that was not theirs.

Original advisory

From the GitHub Advisory Database (CC BY 4.0).

Summary

In the documented multi-user HTTP deployment (--transport streamable-http with global operator Atlassian credentials), sooperset/mcp-atlassian exposes all tools to unauthenticated network clients, and the upload_attachment tool reads an attacker-supplied file_path with no path validation. Chained, an unauthenticated network attacker reads arbitrary files on the MCP server host (e.g. /proc/self/environ → the operator's Atlassian API token + .env secrets, ~/.ssh/id_rsa, /etc/passwd) by uploading them to an attacker-chosen page/issue and reading them back.

Details

Missing authentication (transport):

  • streamable-http binds 0.0.0.0 by default (src/mcp_atlassian/__init__.py:151).
  • The OAuth-proxy auth provider is opt-in (ATLASSIAN_OAUTH_PROXY_ENABLE, default false), so main_mcp is built with auth=None (src/mcp_atlassian/servers/main.py:724-731, 813-817).
  • UserTokenMiddleware._parse_auth_header sets auth_validation_error only for a *malformed* Authorization header; a request with no Authorization header passes through (main.py:416-446, 582-595).
  • _get_fetcher then falls through to the global credential fallback using the operator's .env Atlassian token (src/mcp_atlassian/servers/dependencies.py:644-676). check_write_access gates only on read-only mode, not auth → read and write tools reachable.

Arbitrary file read (sink):

  • upload_attachment's file_path flows unsanitized into open(file_path, 'rb') — Confluence src/mcp_atlassian/confluence/attachments.py:477 (from servers/confluence.py:1294-1369); Jira src/mcp_atlassian/jira/attachments.py:386 (from servers/jira.py:1609-1673). No validate_safe_path / allowlist (contrast the download flow, hardened after CVE-2026-27825).

Proof of Concept

# unauthenticated (no Authorization header) against a default streamable-http deployment:
tools/call upload_attachment { "file_path": "/proc/self/environ", "page_id": "<attacker-chosen>" }
# then read it back:
tools/call download_attachment { ... }   # returns the bytes (base64) -> operator's ATLASSIAN token + .env secrets

Impact

Unauthenticated arbitrary local file read on the MCP server host — including the operator's Atlassian API token and .env secrets — a boundary the Atlassian-scoped tool must not cross, plus unauthenticated use of every read/write Atlassian tool as the operator's (often admin) principal. Distinct from GHSA-xjgw-4wvw-rgm4 (file *write* via download_path) and GHSA-7r34-79r5-rcc9 (URL-header SSRF).

Suggested fix

Require authentication on the streamable-http transport by default (do not fall back to operator global credentials for unauthenticated requests); apply validate_safe_path/allowlist to file_path in upload_attachment as the download flow already does.

Affected

mcp-atlassian <= 0.21.1.

Credited to koonnamchok.

Questions

Is a login needed to read files with this flaw?

No. A request with no Authorization header passes the middleware on a default streamable-http deployment and runs with the operator's global credentials.

Which secrets are at risk?

Anything the server process can read: the operator's Atlassian API token and .env values via /proc/self/environ, SSH private keys, and system files such as /etc/passwd.

How does the attacker get the file back?

They upload it as an attachment to a page or issue of their choosing, then call download_attachment, which returns the bytes base64-encoded.

References

How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. The analysis is written by an AI model from the sources listed above and checked by automated rules before it is published. Check versions against the vendor's advisory before you act. Methodology

More Other MCP servers and tools vulnerabilities

All Other MCP servers and tools entries