MCP Atlassian: Unauthenticated arbitrary local file read via upload_attachment file_path, chained with missing auth on streamable-http transportGHSA-cc5h-2pwp-pvcc
HIGHFix: sooperset/mcp-atlassian#1448GHSA-cc5h-2pwp-pvcc is a high-severity (CVSS 8.6) Path Traversal vulnerability in mcp-atlassian. A fix is available for mcp-atlassian — see the affected versions and patch details below.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
GHSA-cc5h-2pwp-pvcc by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.
Where this sits among everything scored
Of 394,803 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.
Real-World Exposure
mcp-atlassianReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
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.0by default (src/mcp_atlassian/__init__.py:151). - The OAuth-proxy auth provider is opt-in (
ATLASSIAN_OAUTH_PROXY_ENABLE, default false), somain_mcpis built withauth=None(src/mcp_atlassian/servers/main.py:724-731, 813-817). UserTokenMiddleware._parse_auth_headersetsauth_validation_erroronly for a malformed Authorization header; a request with no Authorization header passes through (main.py:416-446, 582-595)._get_fetcherthen falls through to the global credential fallback using the operator's.envAtlassian token (src/mcp_atlassian/servers/dependencies.py:644-676).check_write_accessgates only on read-only mode, not auth → read and write tools reachable.
Arbitrary file read (sink):
upload_attachment'sfile_pathflows unsanitized intoopen(file_path, 'rb')— Confluencesrc/mcp_atlassian/confluence/attachments.py:477(fromservers/confluence.py:1294-1369); Jirasrc/mcp_atlassian/jira/attachments.py:386(fromservers/jira.py:1609-1673). Novalidate_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.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | mcp-atlassian | all versions | 0.22.0pip install --upgrade 'mcp-atlassian==0.22.0' |
Affected Products
mcp atlassianmcp-atlassianDetection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for mcp-atlassian, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update mcp-atlassian to 0.22.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-cc5h-2pwp-pvcc is resolved across your whole dependency graph.
Workarounds
Resolve every user-supplied path to its canonical form and reject anything that escapes the intended directory, and run the component under an account that has no read or write access outside the directory it legitimately serves.
Frequently Asked Questions
Is GHSA-cc5h-2pwp-pvcc in your dependencies?
Find it across PyPI, including transitive dependencies.