romain-deperne/CVE-2026-27825

GitHub: romain-deperne/CVE-2026-27825

针对 mcp-atlassian 中 confluence_upload_attachment 路径穿越漏洞(CVE-2026-27825)的完整端到端 PoC 复现,揭示了不对称补丁修复导致的安全盲区。

Stars: 0 | Forks: 0

# CVE-2026-27825 — mcp-atlassian 中通过 confluence_upload_attachment 实现的路径穿越 **严重性**:Critical (CVSS 9.3) **CWE**:CWE-22 — 路径穿越 **受影响组件**:`sooperset/mcp-atlassian` >= 0.17.0 (GHSA-xjgw-4wvw-rgm4 的读取端孪生漏洞) **安全通告**:GHSA **NVD**:https://nvd.nist.gov/vuln/detail/CVE-2026-27825 ## 太长不看 `confluence_upload_attachment` MCP 工具将其 `file_path` 参数直接传递给 `open(file_path, "rb")`,而没有进行任何路径验证。能够调用该工具的攻击者可以从服务器文件系统读取任意文件,并通过 multipart 上传将其渗透到攻击者控制的 Confluence endpoint。默认的 `streamable-http` 传输绑定到 `0.0.0.0` 且无身份验证,使得该漏洞在无需凭证的情况下即可被远程利用。 这是先前已修补的 GHSA-xjgw-4wvw-rgm4 的**读取端对称孪生漏洞** —— v0.17.0 的修复仅涵盖了写入/下载路径。上传路径则未设防。 ## 我是如何发现此漏洞的 mcp-atlassian 曾在 v0.17.0 (GHSA-xjgw-4wvw-rgm4) 中收到过一次路径穿越修复,该补丁修补了**写入路径** —— 即将附件下载到本地磁盘的情况。我的假设是:当对一个对称操作的一个方向应用了修复时,另一个方向往往会被忽略。 我打开了 `attachments.py` 并搜索了所有的 `open(` 调用。下载路径(第 223、272 行)在 `open()` 之前添加了 `validate_safe_path(local_path)`。而上传路径(第 477 行)则没有任何校验。相同的文件,相同的模式,却采用了不一致的处理方式 —— 典型的不完整修复。 工具定义也证实了这一点:`file_path: Annotated[str, Field(description="Absolute path to the file to upload")]` 没有 `pattern=` 约束,没有验证器,什么都没有。该字段在文档中被明确定义为接受绝对路径且无任何限制。 我进行了端到端复现:启动了真实的 `mcp-atlassian` 服务器进程,使用 MCP stdio 客户端 (`mcp.ClientSession`) 驱动它,将其指向本地模拟的 Confluence HTTP stub,并使用 `file_path=/etc/passwd` 调用 `confluence_upload_attachment`。mock 服务器在 multipart 请求体中记录了完整的 `/etc/passwd` 内容。进行了两次完整的复现运行,所有日志均记录在 PoC 文件中。 默认的 `HOST=0.0.0.0` 绑定且无身份验证,使得该漏洞在默认部署中无需凭证即可被远程利用。 ## 受影响的组件 **文件**:`src/mcp_atlassian/confluence/attachments.py`,第 477 行 ``` with open(file_path, "rb") as fp: # ← file_path is attacker-controlled files = {"file": (filename, fp, content_type)} response = self.confluence.session.post(url, files=files, ...) ``` **工具定义** (`src/mcp_atlassian/servers/confluence.py:1307`): ``` file_path: Annotated[str, Field(description="Absolute path to the file to upload")] # 没有 pattern=,没有 validator,没有 validate_safe_path() ``` **与已修补的下载路径的不对称性:** ``` # attachments.py:223 — 已修补(下载路径) validate_safe_path(local_path) # ← guard added in v0.17.0 open(local_path, "wb") # attachments.py:477 — 存在漏洞(上传路径) open(file_path, "rb") # ← no guard, missed in v0.17.0 ``` ## 根本原因 针对 GHSA-xjgw-4wvw-rgm4 的 v0.17.0 补丁在写入端(将附件下载到本地磁盘)添加了 `validate_safe_path()` 调用,但并未审计读取端(将本地文件上传到 Confluence)。`check_write_access` 装饰器与此无关 —— 它仅用于限制 `READ_ONLY_MODE`。 **默认网络暴露面** (`src/mcp_atlassian/__init__.py:151`): ``` HOST = "0.0.0.0" # binds all interfaces # streamable-http transport 中没有 auth 层 ``` ## PoC 针对模拟 Confluence API 的本地 HTTP stub 进行了完全的端到端复现。参见 [`mcp_client.py`](./mcp_client.py)、[`mock_confluence.py`](./mock_confluence.py) 和 [`poc_run1.sh`](./poc_run1.sh)。 ``` # poc_run1.sh — 通过 confluence_upload_attachment 读取 /etc/passwd # 1. 启动 mock Confluence endpoint python mock_confluence.py & # 2. 使用 path traversal payload 调用 MCP tool python mcp_client.py \ --tool confluence_upload_attachment \ --page-id 123456 \ --file-path /etc/passwd \ --filename passwd.txt # → mock_confluence.py 日志中出现 /etc/passwd 内容 ``` ## 影响 1. **任意文件读取** —— 服务器进程可读的任何文件(`/etc/passwd`、SSH 密钥、`.env`、应用程序 secrets) 2. **远程、无需身份验证** —— 默认的 `streamable-http` 传输绑定到 `0.0.0.0`,无身份验证;任何可达网络的攻击者都可以直接调用 MCP 工具 3. **影响范围改变** —— 预期 Confluence 附件边界之外的文件被渗透出去 → CVSS 中的 S:C ## 时间线 - **发现**:2026-04-11 - **报告**:GHSA 私有安全通告 - **CVE 发布**:CVE-2026-27825
标签:0.0.0.0监听, API安全, Atlassian, CISA项目, Confluence, CVE-2026-27825, CVSS 9.3, CWE-22, HTTP工具, JSON输出, mcp-atlassian, MCP协议, Python, ZIP文件解压, 严重漏洞, 中间件安全, 任意文件读取, 企业协作, 文件上传漏洞, 文件系统攻击, 无后门, 服务端请求伪造, 未授权访问, 权限验证缺失, 漏洞复现, 编程工具, 网络安全, 网络安全审计, 路径遍历, 远程代码执行, 逆向工具, 隐私保护