
ماسح ضوئي غير متصل لـ 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 advisory | 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، ولا تدّعي تغطية الكل.
لم تُدرَج groupIds أخرى (مثل 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:
test / provided dependencies to
downstream consumers, so pac4j-jwt never reaches their runtime classpath.pac4j-oidc-6.0.0.jar has 78 entries, all under
org/pac4j/oidc/, with no shaded pac4j-jwt classes.Root cause: v0.1.0 did parse every pom, but only looked at who names the coordinate,
never at scope — mistaking "declared in a pom" for "reaches the consumer".
If you upgraded pac4j because of a v0.1.0 report, that upgrade was not required (though harmless). Action is only needed when an affected
pac4j-jwtis actually present.
Deciding whether an affected pac4j-jwt is actually on a given machine defeats
mvn dependency:tree in two common cases: a production box with only a packaged fat-jar
(no sources, no pom), or a copy shaded inside some vendor SDK, invisible to the dependency
tree. This tool inspects the artifacts themselves.
| Artifact | Affected versions | In official advisory |
|---|---|---|
org.pac4j:pac4j-jwt | 114 | ✅ the only one listed — and that is correct |
java -jar pac4j-check.jar ./myapp.jar
java -jar pac4j-check.jar /opt/apps
java -jar pac4j-check.jar /opt/apps --json
Exit codes: 0 clean · 1 disputed/undetermined · 2 affected.
mvn dependency:tree cannot seeVerdicts follow the official advisory GHSA-pm7g-w2cf-q238 exactly:
pac4j-jwt < 4.5.9 -> 4.5.9
pac4j-jwt >= 5.0.0-RC1 and < 5.7.9 -> 5.7.9
pac4j-jwt >= 6.0.4.1 and < 6.3.3 -> 6.3.3
Cross-check: running the rules over all 147 published pac4j-jwt versions yields 114
affected — exactly matching the advisory's three ranges (13+33+68). This is asserted in
OfficialRangeCrossCheckTest; a mismatch fails the build.
Two limitations, stated plainly:
org.pac4j groupId is covered. Third-party research reports 19 affected
packages across 1,020 versions but has not published the full list. This tool independently
reconstructs the org.pac4j portion and does not claim full coverage.6.0.4.1; third-party research states the flaw was introduced as early as
1.9.2. We have not independently verified the latter, so these versions are flagged for
human review with a conservative upgrade recommendation rather than asserted as vulnerable.A wrong verdict is not a "false positive" — it makes people take the wrong action.
Apache License 2.0
هذه الأداة تجيب على سؤال «هل أنا مصاب أم لا». أما ما يلي فهي لا تستطيع الإجابة عليه، ويمكنك التواصل معي للقيام به:
📮 [email protected] —— اشرح الحالة، وسأعطيك ردًا مكتوبًا في صفحة واحدة خلال 24 ساعة: هل يمكن القيام به، وأين الصعوبة، وكم يستغرق تقريبًا. هذه الخطوة مجانية، ولا تتطلب منك أي التزام مسبق.