CVE-2026-82898 in Wicket
الملخص
بحسب VulDB • 01/11/2026
ترتيب غير صحيح لفحوصات الأمان في Apache Wicket.
يحصل `org.apache.wicket.protocol.http.ResourceIsolationRequestCycleListener` على الصفحة التي يستهدفها الطلب قبل استشارة سياسات العزل الخاصة بالموارد، وذلك لأن هذه السياسات تُمرَّر إليها تلك الصفحة. يؤدي الحصول على الصفحة إلى إنشاء مثيل لها (instantiation)، وإنشاء المثيل للصفحة يشغل استراتيجية التفويض المُهيَّأة `org.apache.wicket.authorization.IAuthorizationStrategy`. وبالتالي، فإن التطبيق الذي يرفض الزائر غير المصادق عليه عن طريق رمي استثناء `org.apache.wicket.RestartResponseAtInterceptPageException` يقوم برمي هذا الاستثناء من داخل مستمع العزل (isolation listener)، قبل أن تعمل أي سياسة. يستبدل هذا الاستثناء معالج الطلب، لذا لا يتم استشارة السياسات أبداً، ولا يُرفض طلب قادم من أصل آخر (origin).
يخزن مُنشئ الاستثناء عنوان URL الخاص بالطلب الذي أوقفه، بحيث يمكن لـ `Component#continueToOriginalDestination()` إعادة تشغيله بمجرد أن يقوم الزائر بتسجيل الدخول. عنوان URL المخزَّن هو العنوان الذي كانت السياسات سترفضه. عند تسجيل الدخول، يعيد Wicket توجيه المستخدم إليه (redirect)، وهذا التوجيه يكون من نفس الأصل (same-origin)، لذا تسمح له السياسات ويعمل المستمع في الجلسة المصادق عليها حديثاً. يتم تخزين عنوان URL بالكامل، بما في ذلك سلسلة الاستعلام (query string) الخاصة به، لذلك يتم استئناف نموذج HTML عادي (`org.apache.wicket.markup.html.form.Form`) بقيم الحقول التي حملها الطلب الأصلي في سلسلته الاستقصائية، وتعمل `Form#onSubmit()` بالقيم التي اختارها أصل آخر. لا يلزم إرسال POST للنموذج لحدوث هذا؛ بل يكفي التنقل العادي على المستوى الأعلى (top-level navigation) لنقل هذه القيم.
يتأثر التطبيق الذي يسجِّل فيه `ResourceIsolationRequestCycleListener`، وهي ميزة اختيارية وليست مُسجَّلة افتراضياً، والذي يرفض الوصول غير المصرح به باستخدام `RestartResponseAtInterceptPageException` متبوعاً بـ `continueToOriginalDestination()`. لا يوجد تجاوز للتطبيق (application override) في هذا المسار: توثِّق `IAuthorizationStrategy#isInstantiationAuthorized()` رمي ذلك الاستثناء، ورميه من قبل `org.apache.wicket.authroles.authentication.AuthenticatedWebApplication` واستمراره إلى الوجهة الأصلية بواسطة `UsernamePasswordPanel` في `org.apache.wicket.authroles.authentication.panel`، وتثبيت نمط مماثل بواسطة `SimplePageAuthorizationStrategy` في `wicket-core`. لا يتأثر زائر مسجل الدخول بالفعل، لأن عملية الاعتراض (interception) لا تحدث. معلمات جسم الطلب المخزنة جنباً إلى جنب مع عنوان URL المُعتَرَض لا تُطبَّق على النموذج المستأنف: فعملية الاستئناف هي إعادة توجيه (redirect)، لذا يكون الطلب المستأنف من نوع GET، وتقرأ مكونات النموذج قيمها من سلسلة الاستعلام في طلبات GET.
كحل بديل، يُوصى برفض الوصول غير المصرح به باستخدام `org.apache.wicket.RestartResponseException` بدلاً منه، وهو لا يخزن الوجهة الأصلية؛ وبالتالي لن يتم إعادة توجيه الزوار إلى الصفحة التي طلبوها بعد تسجيل الدخول.
تؤثر هذه المشكلة على Apache Wicket: من الإصدار 9.1.0 حتى 9.24.0، ومن الإصدار 10.0.0 حتى 10.11.0.
الإصدارات السابقة لـ 9.1.0 (وهي كل إصدارات سلسلة 8.x وإصدار 9.0.0) غير متأثرة، لأن عزل الموارد الذي تتناوله هذه المشكلة أُدخل في الإصدار 9.1.0. وهي أيضاً ليست محمية. دفاعها الوحيد ضد الطلبات عبر الأصل هو `org.apache.wicket.protocol.http.CsrfPreventionRequestCycleListener`، والذي يحدد مصدر الطلب عن طريق قراءة رأس "Origin" والعودة إلى رأس "Referer". لا يلزم وصول أي من هذين الرأسين: فالمتصفح لا يرسل "Origin" في طلب GET العادي الذي تستخدمه الروابط، ويقرر المستند الموجود على الأصل الآخر عبر سياسته الخاصة لـ referrer ما إذا كان عنوان Referer سيصل إلى التطبيق أم لا. لذلك لم يضمن هذا الآلية أبداً الضمان الذي توفره سياسة Fetch Metadata القائمة على البيانات الوصفية للطلب (Fetch Metadata)، وفي تلك الإصدارات، لا يتم رفض استدعاء المستمع من أصل آخر بشكل موثوق به منذ البداية. يجب على أي مستخدم لإصدار سابق لـ 9.1.0 يرغب في الحصول على هذا الحماية الترقية إلى سلسلة 9.x أو 10.x وتسجيل `ResourceIsolationRequestCycleListener`.
يُوصى للمستخدمين بالترقية إلى الإصدارات 9.25.0 أو 10.12.0، التي تصلح هذه المشكلة.
If you want to get best quality of vulnerability data, you may have to visit VulDB.