
ماسح ضوئي غير متصل لـ CVE-2026-29000 (CVSS 10.0) في org.pac4j:pac4j-jwt. يفحص ملفات jar/fat-jars مباشرةً، لذا يعمل حيث لا يستطيع mvn dependency:tree العمل. ملف jar واحد، بدون تبعيات، Java 8+.
فحص دون اتصال لـ CVE-2026-29000 (CVSS 10.0) —— بما في ذلك الحزم التي لم يدرجها التنبيه الرسمي.
English | 中文
ملف jar واحد، بحجم ~24KB، بدون أي تبعيات وقت التشغيل، يعمل من Java 8 فما فوق، يعمل دون اتصال بالكامل، ولا يرسل أي بيانات إلى أي مكان.
JwtAuthenticator في org.pac4j:pac4j-jwt لا يفرض التحقق من التوقيع عند معالجة رموز JWT المشفّرة (JWE).
يكفي أن يحصل المهاجم على المفتاح العام RSA للخادم (والمفتاح العام علني بطبيعته)،
ليتمكن من إنشاء PlainJWT مغلّف داخل JWE، وكتابة قيمة subject والدور كما يشاء،
والدخول بأي هوية مستخدم، بما في ذلك المدير. دون أي بيانات اعتماد.
| البند | القيمة |
|---|---|
| CVE | CVE-2026-29000 |
| تنبيه GitHub | GHSA-pm7g-w2cf-q238 |
| CVSS | 10.0 (الدرجة الكاملة) |
| تاريخ النشر | 2026-03-05 |
يُدمج pac4j على نطاق واسع في Spring Security وApereo CAS وJEE وVert.x وPlay وDropwizard وغيرها.
ادّعى v0.1.0 أن «قاعدة الثغرات الرسمية أدرجت حزمة واحدة فقط، بينما هناك خمس حزم»،
وبناءً على ذلك أبلغ عن pac4j-oidc / javalin-pac4j / lagom-pac4j / ratpack-pac4j كمتأثرة.
كانت تلك إنذارات خاطئة. إدراج التنبيه الرسمي لـ pac4j-jwt فقط هو الصحيح.
أساس المراجعة (دليلان مستقلان، وكلاهما قابل لإعادة الإنتاج ذاتيًا):
| المكوّن | كيف يعلن اعتماده على pac4j-jwt | هل ينتقل إلى المستخدم |
|---|---|---|
pac4j-oidc | نطاق test (تم التحقق إصدارًا بإصدار: 3.0.0 / 4.0.0 / 4.5.0 / 5.0.0 / 5.7.0 / 6.0.0 / 6.3.0) | ❌ |
javalin-pac4j | نطاق test | ❌ |
lagom-pac4j-parent | نطاق provided | ❌ |
ratpack-pac4j:1.4.6 | كتلة الاعتماد تلك مغلّفة بالكامل داخل تعليق XML، فهي غير موجودة أصلًا | ❌ |
test / provided لا تنتقل إلى المستهلكين downstream،
فلن يظهر pac4j-jwt على runtime classpath الخاص بالمستخدم.pac4j-oidc-6.0.0.jar على 78 مدخلًا، جميعها تحت org/pac4j/oidc/،
ولا توجد أي أصناف pac4j-jwt مدمجة (shaded) بداخله. فلا هو ينتقل، ولا هو يحملها.أين كان الخطأ: حلّل v0.1.0 كل ملف pom على حدة، لكنه نظر فقط إلى «من كتب إحداثية pac4j-jwt»،
ولم ينظر إلى scope —— فاعتبر «مكتوب في pom» مساويًا لـ«سيصل إلى المستخدم».
إذا كنت قد رقّيت pac4j بسبب تقرير v0.1.0، فذلك الترقية لم تكن ضرورية (والترقية نفسها غير ضارة). لا حاجة لأي إجراء إلا إذا كان
pac4j-jwtبإصدار متأثر موجودًا فعلًا في تطبيقك.
لتحديد ما إذا كان pac4j-jwt المتأثر موجودًا فعلًا على جهاز معيّن، تفشل mvn dependency:tree في حالتين ——
إذ لا يوجد على جهاز الإنتاج سوى fat-jar جاهز (بلا مصدر ولا pom)؛ أو أنه مدمج (shaded) داخل أحد الـ SDK،
فلا يظهر في شجرة الاعتمادات أصلًا. تفحص هذه الأداة المكوّن نفسه مباشرة، دون الاعتماد على بيئة البناء.
| المكوّن | عدد الإصدارات المتأثرة | التنبيه الرسمي |
|---|---|---|
org.pac4j:pac4j-jwt | 114 | ✅ الوحيد المُدرج، وهذا صحيح |
java -jar pac4j-check.jar ./myapp.jar # فحص ملف jar/war واحد
java -jar pac4j-check.jar /opt/apps # فحص مجلد (بشكل تكراري)
java -jar pac4j-check.jar /opt/apps --json # إخراج JSON، مناسب للربط بأنابيب المعالجة
java -jar pac4j-check.jar ./app.jar --gbk # عند ظهور رموز مشوّهة في وحدة تحكم Windows
رموز الخروج: 0 = لم يُعثر على متأثر · 1 = محلّ شك/تعذّر التحديد · 2 = تم العثور على متأثر. يمكن ربطه مباشرة بـ CI.
[CRITICAL] pac4j-jwt 5.4.3
位置 :demo-app.jar!/BOOT-INF/lib/pac4j-jwt-5.4.3.jar
版本来源:pom.properties(可靠)
部署形态:Spring Boot fat-JAR
结论 :命中 CVE-2026-29000 —— JWE 处理路径未强制校验签名,
拿到服务器 RSA 公钥即可伪造任意身份(含管理员)登录
处置 :升级 pac4j-jwt 至 5.7.9
كان v0.1.0 يضيف هنا سطرًا آخر
[CRITICAL] pac4j-oidc—— وكان ذلك إنذارًا خاطئًا، وقد حُذف في v0.2.0، والسبب موضّح في تصحيح المقدمة.
mvn dependency:tree كشفهاالحكم يستند دائمًا إلى التنبيه الرسمي GHSA-pm7g-w2cf-q238:
pac4j-jwt < 4.5.9 -> 升 4.5.9
pac4j-jwt >= 5.0.0-RC1 且 < 5.7.9 -> 升 5.7.9
pac4j-jwt >= 6.0.4.1 且 < 6.3.3 -> 升 6.3.3
التحقق الذاتي: تشغّل هذه الأداة قواعد الحكم على جميع إصدارات pac4j-jwt الـ147 على Maven Central،
ويكون عدد الإصابات 114، وهو مطابق تمامًا لمجموع أعداد الإصدارات في نطاقات التنبيه الرسمي الثلاثة (13+33+68).
هذا التأكيد مكتوب في الاختبار (OfficialRangeCrossCheckTest)، وأي عدم تطابق يُفشل البناء.
⚠️ لكن يجب أن تعرف ما الذي يتحقق منه هذا فعلًا: إنه يتحقق من صحة خوارزمية النطاقات الإصدارية، ولا يمكنه التحقق من «أي المكوّنات يجب أن تدخل جدول الحكم» —— فالإنذار الخاطئ في v0.1.0 حدث بالضبط في الجانب الثاني، بينما كان هذا التحقق الذاتي أخضر آنذاك. نطاق نجاح التحقق ≠ نطاق صحة الاستنتاج.
يغطي فقط groupId واحدًا هو org.pac4j.
هناك أبحاث من أطراف ثالثة تقول إن المكوّنات المتأثرة 19 مكوّنًا و1,020 إصدارًا، لكنها لم تنشر القائمة الكاملة.
ما تعيد هذه الأداة بناءه بشكل مستقل هو الجزء الخاص بـ org.pac4j، ولا تدّعي تغطية الكل.
لم يتم تضمين groupId أخرى (مثل org.apereo.cas الخاص بـ Apereo CAS).
يُصنّف pac4j-jwt 6.0.0 ~ 6.0.4 كـ«محلّ شك» وليس «متأثر».
تقول الجهة الرسمية إن 6.x متأثر بدءًا من 6.0.4.1؛ بينما تقول أبحاث طرف ثالث إن الثغرة أُدخلت منذ 1.9.2 ——
وإن صحّ ذلك، فيجب اعتبار هذه الإصدارات الخمسة متأثرة أيضًا. لم نتحقق بشكل مستقل من استنتاج الطرف الثالث،
لذلك نُبرزها منفصلة ونوصي بترقية تحوّطية، بدلًا من الحكم عليها كمتأثرة مباشرة.
لماذا كل هذا التحوّط: خطأ قاعدة الحكم ليس «إنذارًا خاطئًا»، بل يدفع المستخدم إلى فعل خاطئ. نفضّل وسمها كمحلّ شك على تثبيت نطاق غير مُتحقق منه كاستنتاج نهائي.
mvn package # الناتج: target/pac4j-check.jar
mvn test # 31 اختبارًا
إذا وجدت خطأ في الحكم، أو حالة فائتة، أو إنذارًا خاطئًا، يُرجى فتح Issue. وإذا أمكنك تقديم إحداثيات مكوّن قابلة لإعادة الإنتاج (groupId:artifactId:version)، فسيكون الإصلاح أسرع بكثير.
Apache License 2.0
Offline scanner for CVE-2026-29000 (CVSS 10.0) — including the packages the official advisory does not list.
Single jar, ~24KB, zero runtime dependencies, Java 8+, fully offline, sends nothing anywhere.
JwtAuthenticator in org.pac4j:pac4j-jwt fails to enforce signature validation on certain
encrypted JWT (JWE) processing paths. An attacker holding the server's RSA public key
(which is public by design) can craft a JWE-wrapped PlainJWT with arbitrary subject and role
claims and authenticate as any user, including administrators — with no credentials.
| CVE | CVE-2026-29000 |
| GitHub advisory | GHSA-pm7g-w2cf-q238 |
| CVSS | 10.0 |
| Published | 2026-03-05 |
v0.1.0 claimed the official advisory "lists only one package while there are five", and
flagged pac4j-oidc / javalin-pac4j / lagom-pac4j / ratpack-pac4j as affected.
Those were false positives. The advisory listing only pac4j-jwt is correct.
| Artifact | How it declares pac4j-jwt | Reaches consumers? |
|---|---|---|
pac4j-oidc | test scope (verified on 3.0.0 / 4.0.0 / 4.5.0 / 5.0.0 / 5.7.0 / 6.0.0 / 6.3.0) | ❌ |
javalin-pac4j | test scope | ❌ |
lagom-pac4j-parent | provided scope | ❌ |
ratpack-pac4j:1.4.6 | the whole block is inside an XML comment — it does not exist | ❌ |
Two independent lines of evidence, both reproducible: