
ثغرة حقن SQL في PyAthena عبر DefaultParameterFormatter (CVE-2026-65321)
الخطورة: حرجة، CVSS v4.0 9.3 / CVSS v3.1 9.8 (مُسندة من VulnCheck، CNA)
المتجه (v4.0): CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
المتجه (v3.1): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
المتأثر: PyAthena <= 3.35.3 (جميع الإصدارات حتى 3.35.3)
تم الإصلاح في: 3.35.4
CWE: CWE-89 (تحييد غير سليم للعناصر الخاصة المستخدمة في أمر SQL، 'حقن SQL')
أبلغ عنها: Rahul Karne
CNA: VulnCheck
نُشر: 3 أغسطس 2026
قام PyAthena بتهريب المدخلات غير الموثوقة بشكل صحيح في استعلامات SELECT وبشكل غير صحيح في استعلامات DELETE.
يختار PyAthena، عميل Python DB-API الخاص بـ Amazon Athena والمستخدم على نطاق واسع، روتين تهريب السلاسل النصية من الكلمة الرئيسية الأولى للعبارة. العبارات التي تبدأ بـ SELECT أو WITH أو INSERT أو UPDATE أو MERGE تتلقى تهريبًا صحيحًا وفق Trino، حيث تُحيَّد علامة الاقتباس المفردة بمضاعفتها (''). أما أي عبارة أخرى، وهي في الغالب DELETE أو CREATE TABLE … AS SELECT (CTAS)، فتؤول إلى تهريب Hive بأسلوب الشرطة المائلة العكسية (\'). محرك Athena هو Trino، الذي يعامل الشرطة المائلة العكسية داخل سلسلة نصية بين علامتي اقتباس مفردة كحرف عادي، لذا فإن تهريب الشرطة المائلة لا يحيد شيئًا. يمكن للمهاجم الذي يستطيع التأثير في معامل نصي في مثل هذه العبارة أن ينهي النص الحرفي ويحقن SQL تعسفيًا، دون مصادقة ودون تفاعل من المستخدم.
لذلك فإن الخلل غائب عن مسار القراءة وموجود بالضبط في أنواع العبارات التدميرية حيث يحدث أكبر ضرر. تُحمَّل الحزمة 22.3 مليون مرة شهريًا.
PyAthena هي مكتبة عميل مجتمعية تابعة لجهة خارجية لـ Amazon Athena. إنها ليست منتجًا من AWS، وهذه ليست ثغرة في AWS أو في Athena نفسها.
يمكن للمهاجم الذي يتحكم في معامل نصي يُمرَّر إلى عبارة قابلة للاستغلال أن يخرج من النص الحرفي المقصود ويغيّر منطق العبارة. الأثر الأكثر مباشرة وقابلية للإثبات بشكل موثوق هو حذف بيانات غير مصرح به: حمولة مثل missing' OR 1=1 -- في استعلام DELETE … WHERE token = %(token)s تحيد مسند WHERE وتحذف كل صف يسمح دور IAM الخاص بمجموعة عمل Athena بحذفه (على سبيل المثال، جميع صفوف جدول Iceberg). وفقًا لنوع العبارة وصلاحيات الدور، قد يتمكن المهاجم أيضًا من إنشاء جداول يعرّفها المهاجم عبر حقن CTAS، وحيثما يمكنه قراءة الجدول الناتج لاحقًا، قد يسرّب بيانات من جداول أخرى يمكن للدور الوصول إليها.
جميع الأثر محدود بصلاحيات مجموعة العمل / دور IAM في Athena التي يستخدمها العميل. هذا حقن في مستوى البيانات في محرك SQL الخاص بـ Athena؛ وهو لا يمنح تنفيذ كود على المضيف الذي يشغّل PyAthena، ولا المساس بـ AWS نفسها.
من المتأثر: التطبيقات التي تستخدم PyAthena < 3.35.4 مع DefaultParameterFormatter الافتراضي (استبدال المعاملات من جانب العميل بأسلوب pyformat / named) التي (1) تبني عبارة لا تبدأ بـ SELECT/WITH/INSERT/UPDATE/MERGE، عمليًا DELETE أو CTAS أو CREATE VIEW أو DROP أو ALTER، و(2) تمرر بيانات متأثرة بالمهاجم كمعامل نصي إلى تلك العبارة.
من غير المتأثر:
3.35.4 أو أحدث.SELECT/WITH/INSERT/UPDATE/MERGE فقط، فهذه تُوجَّه إلى مُهَرِّب المضاعفة الآمن.| المقياس | القيمة | المصدر |
|---|---|---|
| التنزيلات، كل الأوقات | 740.6M | pepy.tech/projects/pyathena |
| التنزيلات، آخر 30 يومًا | 22.3M | pepy.tech |
| التنزيلات، آخر 24 ساعة | 221.0K | pepy.tech |
| معدل التثبيت المستمر | 8.95/ثانية | pepy.tech |
| مستهلكون مهمون في المصب | dbt-athena يستورد _escape_hive و_escape_presto من pyathena.formatter مباشرة | connections_legacy.py#L23-L27 |
يختار DefaultParameterFormatter.format() دالة تهريب السلاسل النصية فقط من الكلمة الرئيسية الأولى للعبارة. فقط قائمة مسموح بها من البادئات تتلقى مُهَرِّب Trino الصحيح؛ أما أي عبارة أخرى فتؤول إلى تهريب Hive بأسلوب الشرطة المائلة العكسية.
# src/pyathena/formatter.py, DefaultParameterFormatter.format(), lines ~271-275 (v3.35.2)
operation_upper = operation.upper()
if operation_upper.startswith(("SELECT", "WITH", "INSERT", "UPDATE", "MERGE")):
escaper = _escape_presto # safe: doubles single quotes
else:
escaper = _escape_hive # UNSAFE for Trino: backslash-escapes quotes
# src/pyathena/formatter.py, lines ~157-165 (v3.35.2)
def _escape_hive(val: str) -> str:
escaped = (
val.replace("\\", "\\\\")
.replace("'", "\\'") # produces \' (not a quote escape in Trino)
.replace("\r", "\\r")
.replace("\n", "\\n")
.replace("\t", "\\t")
)
return f"'{escaped}'"
محرك SQL في Amazon Athena هو Trino (Presto في إصدارات المحرك الأقدم). في Trino، التهريب الوحيد لعلامة الاقتباس المفردة داخل سلسلة نصية بين علامتي اقتباس مفردة هو مضاعفتها ('')؛ أما الشرطة المائلة العكسية فهي حرف عادي. لذلك فإن _escape_hive لا يحيد علامة الاقتباس إطلاقًا بالنسبة إلى Athena، بل يُخرج ... = 'missing\' OR 1=1 -- '، التي يفسّرها Trino على أنها النص الحرفي 'missing\' متبوعًا بـ OR 1=1 -- '، أي SQL يتحكم به المهاجم.
التصميم خطير عند الفشل: فهو يضع قائمة مسموح بها للمسار الآمن ويجعل كل ما عداه افتراضيًا على المُهَرِّب غير الآمن. الإصلاح من المنبع يعكس هذا إلى آمن عند الفشل (الافتراضي إلى مُهَرِّب Trino؛ واستخدام تهريب Hive فقط لـ Hive DDL الحقيقي مثل CREATE DATABASE/DROP TABLE/MSCK REPAIR، مع معاملة CTAS وCREATE VIEW كـ Trino)، ويضيف أيضًا إزالة تعليقات SQL الافتتاحية بحيث لا يمكن لبادئة /* … */ DELETE … أن تهزم اكتشاف نوع العبارة.
_escape_hive ليست sanitization مفقودة، بل هي sanitization بحد ذاتها. إنها روتين تهريب صحيح ومكتمل البناء لقواعد السلاسل النصية في Hive، مطبَّق على محرك يستخدم قواعد Trino. أدوات تتبع التلوث (Taint-tracking) تصمم حقن SQL على أنه وصول بيانات غير موثوقة إلى نقطة استهلاك دون المرور عبر مُهَرِّب؛ وهنا تمر البيانات عبر مُهَرِّب في كل مسار، ويبدو المُهَرِّب تمامًا ككود معالجة لأنه كود معالجة بالفعل، لكن للهجة الخاطئة.
صحة اللهجة ليست خاصية تتبع تلوث، لذلك لا توجد قاعدة تتبع تلوث تقيّمها. الخلل غير مرئي بنيويًا لدى CodeQL وSemgrep وSnyk وSocket، وليس مجرد إغفال منهم، وهذا هو سبب استمراره في حزمة تُثبَّت حوالي تسع مرات في الثانية.
يحتاج المهاجم إلى:
< 3.35.4 مع منسّق المعاملات الافتراضي من جانب العميل (pyformat / named paramstyle).SELECT/WITH/INSERT/UPDATE/MERGE، عمليًا DELETE أو CTAS.المعاملات الرقمية، وأي عبارة تُوجَّه إلى المُهَرِّب الآمن، غير قابلة للاستغلال عبر هذا الخلل.
يستدعي إثبات المفهوم منسّق PyAthena الحقيقي غير المعدّل (مستوردًا من إصدار PyPI المنشور، وليس إعادة بناء) وينفّذ مخرجاته ضد قاعدة بيانات DuckDB محلية في الذاكرة. لا حساب AWS، ولا بيانات اعتماد، ولا وصول إلى الشبكة. إعادة الإنتاج الكاملة تتم بأمرين:
pip install pyathena==3.35.2 duckdb
python poc_pyathena_cna_demo.py --no-pause
المصدر: poc_pyathena_cna_demo.py
عرض مسجّل: شاهد العرض