Jul 11, 2026·7 min read·24 visits
mcp-atlassian prior to 0.22.0 is vulnerable to directory traversal via the confluence_upload_attachment tool, allowing arbitrary local file exfiltration to Confluence. This can be exploited remotely via indirect prompt injection.
A directory traversal vulnerability exists in the mcp-atlassian integration server prior to version 0.22.0. The confluence_upload_attachment tool fails to restrict the paths of uploaded files, allowing authenticated users or external prompt injection payloads to retrieve and exfiltrate arbitrary files from the server's filesystem into Confluence.
The Model Context Protocol (MCP) is an open standard designed to enable large language model (LLM) agents to interact securely with external tools, APIs, and data sources. The mcp-atlassian package implements this protocol to expose Atlassian Jira and Confluence APIs directly to LLM applications. Among the various tools provided by this server, the confluence_upload_attachment tool is designed to allow agents to upload files from the local filesystem of the hosting machine to a specific page in Confluence.
In versions of mcp-atlassian prior to 0.22.0, the file path supplied to the confluence_upload_attachment tool is processed without any validation against directory boundaries. This omission introduces a directory traversal vulnerability classified under CWE-22, enabling unauthorized access to the host file system. Since the tool executes in the security context of the server process, it can access any file readable by the underlying operating system user.
The exposure is heavily magnified by the typical operating context of LLM agents, which often process untrusted external data. If an agent is directed to read a document containing a malicious payload, an external attacker can execute an Indirect Prompt Injection (IPI) attack. This attack tricks the LLM into calling the vulnerable upload tool with arbitrary file paths, exfiltrating critical system secrets back to the attacker-controlled Confluence space.
The primary defect lies in the path normalization and validation logic within the Confluence attachment component of mcp-atlassian. When a tool call is initiated, the server invokes the upload_attachment method inside src/mcp_atlassian/confluence/attachments.py. This method takes a user-controlled parameter file_path representing the file to be uploaded.
The vulnerable implementation relies solely on os.path.abspath(file_path) to resolve relative paths to absolute paths. While this expansion standardizes the path string, it lacks any boundary checking to verify if the resolved path resides within an approved folder. The code then uses os.path.exists(file_path) to confirm the file is present on disk, which succeeds for any accessible path.
Following this check, the path is forwarded directly to the private helper method _upload_attachment_direct. This method opens the file for reading using the built-in open(file_path, "rb") function without further restriction. The binary content of the file is then wrapped in a standard multipart/form-data request and transmitted to the remote Confluence REST API endpoint. Consequently, any system file that the running process has permission to read can be successfully uploaded and exfiltrated.
A comparative analysis of the codebase reveals the vulnerable path handling versus the corrected validation pattern. In version 0.21.1, the input is processed without strict security controls.
# Vulnerable implementation in v0.21.1
try:
# Convert to absolute path if relative
if not os.path.isabs(file_path):
file_path = os.path.abspath(file_path)
# Check if file exists
if not os.path.exists(file_path):
logger.error(f"File not found: {file_path}")
return {"success": False, "error": f"File not found: {file_path}"}In version 0.22.0, the developer introduced the validate_safe_path utility to restrict the resolution of the file_path parameter to the current working directory.
# Patched implementation in v0.22.0
try:
# Confine the upload source to the workspace before it is read
file_path = str(validate_safe_path(file_path))
# Check if file exists
if not os.path.exists(file_path):
logger.error(f"File not found: {file_path}")
return {"success": False, "error": f"File not found: {file_path}"}The validate_safe_path function, implemented in src/mcp_atlassian/utils/io.py, enforces security boundaries by resolving symlinks and explicitly validating containment. It obtains the absolute path of the base directory (defaulting to the current working directory) using Python's Path.resolve(). It then verifies if the target path is a subpath of the base directory using is_relative_to(). If the validation fails, a ValueError is raised, preventing the file open operation.
# Path validation logic in src/mcp_atlassian/utils/io.py
def validate_safe_path(
path: str | os.PathLike[str],
base_dir: str | os.PathLike[str] | None = None,
) -> Path:
if base_dir is None:
base_dir = os.getcwd()
resolved_base = Path(base_dir).resolve(strict=False)
p = Path(path)
if not p.is_absolute():
p = resolved_base / p
resolved_path = p.resolve(strict=False)
if not resolved_path.is_relative_to(resolved_base):
raise ValueError(
f"Path traversal detected: {path} resolves outside {resolved_base}"
)
return resolved_pathThe patch is robust because it addresses several common bypass techniques. By resolving symlinks using Path.resolve(strict=False), it prevents attackers from using symlink directory traversal to reference files outside the workspace. Furthermore, restricting the default base directory to the current working directory minimizes the exposed attack surface, provided the server process is executed from an isolated, empty directory.
Exploitation can proceed via direct tool invocation or indirect prompt injection. In direct exploitation, an attacker who has authenticated access to the MCP client session issues a request payload targeting sensitive files.
An indirect prompt injection attack requires no credentials and operates through the data ingestion pipeline of the LLM. The attacker places a malicious payload inside an external resource, such as a Jira description or comment, that the agent is scheduled to read.
When the agent processes this content, the instruction-following nature of the LLM is subverted by the injection payload. The LLM interprets the text as a high-priority system command. It then issues an automated tool call to confluence_upload_attachment with the file_path set to a target file such as /proc/self/environ or /etc/passwd.
The host process executes the request autonomously without requiring human authorization. Once the upload completes, the file is available under the page attachments on the targeted Confluence page. The attacker can then view or download the attachment directly, exposing sensitive credentials and system details.
The security consequences of this directory traversal flaw are significant. An attacker can retrieve configuration files, source code, and active process memory data. On Linux systems, reading /proc/self/environ exposes all environment variables of the running shell.
These environment variables typically contain the credentials needed for the mcp-atlassian server to authenticate to the cloud APIs. Specifically, this includes CONFLUENCE_API_TOKEN, JIRA_API_TOKEN, and potentially AWS, GCP, or Azure secret keys used for deployment. Compromise of these tokens allows the attacker to hijack the associated Atlassian workspace accounts, gaining access to confidential corporate databases, wikis, and task trackers.
This vulnerability receives a CVSS score of 7.7. The CVSS vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N reflects the ease of exploitation over the network and the high confidentiality impact. The Scope parameter is marked as Changed (S:C) because the vulnerability on the local server hosting the MCP integration directly leads to data exfiltration and credential exposure on the external Confluence Cloud infrastructure.
Immediate remediation requires upgrading mcp-atlassian to version 0.22.0 or higher. This ensures that all file uploads are restricted to the workspace directory. If an upgrade cannot be performed immediately, several workarounds can help reduce the risk of exploitation.
Deploying the server process with minimal privileges is a key defense. The operating system user running the process should have no read access to sensitive system paths or configuration directories. Additionally, running the process within a sandboxed environment, such as a Docker container with a read-only filesystem, restricts the impact of any file-read capabilities.
Monitoring network traffic and application logs can help detect exploitation attempts. Security teams should analyze Confluence audit logs for unexpected attachment uploads, particularly files originating from system directories or those with unusual extensions. Implementing strict Web Application Firewall (WAF) or network detection rules can block patterns matching directory traversal vectors in API parameters.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
mcp-atlassian sooperset | < 0.22.0 | 0.22.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Network |
| CVSS Score | 7.7 (High) |
| Exploit Status | PoC Available |
| Affected Component | confluence_upload_attachment tool |
| Fixed Version | 0.22.0 |
The software 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 software 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.
CVE-2026-14669 is a critical heap-based buffer overflow vulnerability in PostgreSQL's date/time formatting function to_char(timestamptz). The flaw arises from unsafe copying of user-controlled timezone abbreviations into a fixed-size internal buffer. An authenticated database user can trigger this issue by setting a long POSIX timezone abbreviation containing custom formatting, allowing them to overwrite adjacent heap structures and hijack execution control to achieve remote code execution (RCE) with the privileges of the 'postgres' operating system user.
An unauthenticated remote denial of service vulnerability exists in the Unleash feature management platform. By submitting a crafted JSON payload containing deeply nested structures to an OpenAPI-validated endpoint, an attacker can trigger uncontrolled recursion within the error formatting module. This leads to a call-stack exhaustion (RangeError: Maximum call stack size exceeded) inside the Node.js runtime, causing the service to crash immediately without recovery.
CVE-2026-63004 is a server-side request forgery (SSRF) vulnerability in the Unleash feature management platform. Authenticated administrators with CREATE_ADDON or UPDATE_ADDON privileges can exploit this vulnerability to initiate requests to loopback addresses, private networks, and cloud metadata endpoints, potentially leading to information disclosure and credential extraction.
Prior to version 8.0.3, Unleash's Markdown event formatter directly mutated the global template-escaping function of the shared mustache Node.js module, resulting in a process-wide security degradation where HTML/Markdown escaping was permanently disabled for the application lifetime.
A critical SQL injection vulnerability exists in the GeoTools open-source Java library. This vulnerability is situated within the post-processing phase of OGC Filter conversion inside the PostGIS DataStore module. Specifically, the `jsonArrayContains` function does not validate or sanitize its arguments before constructing PostgreSQL SQL/JSON path evaluation queries. An unauthenticated remote attacker can exploit this weakness by submitting crafted filters via standard OGC services like WFS or WMS to execute arbitrary SQL commands on the underlying database system.
CVE-2026-61824 is a high-severity Cross-Site Scripting (XSS) vulnerability in kepano/defuddle before version 0.19.1. Custom site extractors for platforms such as X/Twitter, Substack, and YouTube constructed HTML representations via template string interpolation without output escaping. This allowed malicious pages to bypass standard parser sanitization routines and execute arbitrary JavaScript.