adx-mcp-server (<= latest, commit 48b2933) contains KQL (Kusto Query Language) injection vulnerabilities in three MCP tool handlers: get_table_schema, sample_table_data, and get_table_details. The table_name parameter is interpolated directly into KQL queries via f-strings without any validation or sanitization, allowing an attacker (or a prompt-injected AI agent) to execute arbitrary KQL queries against the Azure Data Explorer cluster.
The MCP tools construct KQL queries by directly embedding the table_name parameter into query strings:
Vulnerable code (permalink):
@mcp.tool(...)
async def get_table_schema(table_name: str) -> List[Dict[str, Any]]:
client = get_kusto_client()
query = f"{table_name} | getschema" # <-- KQL injection
result_set = client.execute(config.database, query)
@mcp.tool(...)
async def sample_table_data(table_name: str, sample_size: int = 10) -> List[Dict[str, Any]]:
client = get_kusto_client()
query = f"{table_name} | sample {sample_size}" # <-- KQL injection
result_set = client.execute(config.database, query)
@mcp.tool(...)
async def get_table_details(table_name: str) -> List[Dict[str, Any]]:
client = get_kusto_client()
query = f".show table {table_name} details" # <-- KQL injection
result_set = client.execute(config.database, query)
KQL allows chaining query operators with | and executing management commands prefixed with .. An attacker can inject:
sensitive_table | project Secret, Password | take 100 // to read arbitrary tables.drop table important_data via get_table_detailsNote: While the server also has an execute_query tool that accepts raw KQL by design, the three vulnerable tools are...
Exploitability
AV:NAC:LPR:LUI:NScope
S:UImpact
C:HI:HA:L8.3/CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L