Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

الخلاصاتاتصالالخصوصية© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
cve-2026-22732-poc — إثبات مفهوم يوضح CVE-2026-22732، وهو خلل في Spring Security حيث يؤدي setIntHeader("Content-Length") إلى إسقاط جميع ترويسات الأمان، مع إصدارات قابلة للاستغلال ومصححة. | Kitploit
أدوات/GitHubGitHub/dylan-chainguard/cve-2026-22732-poc
أدوات دفاعيةتحليل الثغرات الأمنيةالاستغلالالمحاكاة الافتراضية للأمانأمن الويبالتعلم والتعليم
GitHubdylan-chainguard/cve-2026-22732-poc

cve-2026-22732-poc

إثبات مفهوم يوضح CVE-2026-22732، وهو خلل في Spring Security حيث يؤدي setIntHeader("Content-Length") إلى إسقاط جميع ترويسات الأمان، مع إصدارات قابلة للاستغلال ومصححة.

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة
عرض المستودع
117منذ 20 أياملم تتم المراجعة بعد

CVE-2026-22732 — إثبات المفهوم

يقوم Spring Security بإسقاط رؤوس أمان استجابة HTTP بصمت. للعرض / الاستخدام التعليمي فقط؛ شغّله فقط مقابل هذا التطبيق المحلي.

CVECVE-2026-22732 (CWE-425)، نُشر في 2026-03-19
CVSS 3.19.1 حرج — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
التبعية المباشرةspring-boot-starter-web + spring-boot-starter-security 2.7.18
المكوّن المصابspring-security-web / -config / -core 5.7.11 — عابر فقط، لا يُذكر أبدًا في pom.xml
المكوّن المُصلَّحspring-security-web 5.7.14-0.cgr.2، يُوصَل إليه بتغيير <version> واحد — انظر الانتقال
تم التحقق علىTomcat 9.0.118، JDK 17.0.18، macOS arm64

النطاقات المتأثرة: 5.7.0–5.7.21، 5.8.0–5.8.23، 6.3.0–6.3.14، 6.4.0–6.4.14، 6.5.0–6.5.8، 7.0.0–7.0.3. يثبّت Spring Boot 2.7.18 إصدار Spring Security 5.7.11، وهو تمامًا داخل النطاق الأول:

$ mvn dependency:tree -Dincludes=org.springframework.security
+- org.springframework.security:spring-security-config:jar:5.7.11:compile
|  \- org.springframework.security:spring-security-core:jar:5.7.11:compile
\- org.springframework.security:spring-security-web:jar:5.7.11:compile

تشغيله

./run.sh        # terminal 1 — builds and starts on :8080 (pins JDK 17)
./exploit.sh    # terminal 2 — drives every endpoint, diffs the headers

يثبّت run.sh قيمة JAVA_HOME لأن Spring Boot 2.7.x لا يمكنه العمل على JDK 25 الذي يحلّه mvn افتراضيًا على هذا الجهاز. تجاوزه باستخدام JAVA_HOME_17=/path/to/jdk17.

كما يبني باستخدام -s settings-chainguard.xml افتراضيًا، لأن الوالد المُصلَّح غير موجود على Maven Central. اضبط MAVEN_SETTINGS=/path/to/your/settings.xml للإشارة إلى مكان آخر، أو MAVEN_SETTINGS= للبناء من Central فقط — وهو ما يعمل مع 2.7.18 الأصلي فقط.

يقرأ exploit.sh إصدارات spring-security-web وspring-boot الفعلية من target/*.jar، لذا تُبلغ لافتته دائمًا عمّا يعمل فعليًا بدلًا من نص ثابت.

الإعداد

لا يطبّق SecurityConfig أي تخصيص للرؤوس على الإطلاق — الإعدادات الافتراضية لـ Spring Security سارية، وهو بالضبط ما يعتمد عليه تطبيق واعٍ أمنيًا. تُعيد كل نقطة نهاية نفس الجسم الحساس:

{"account":"4111-1111-1111-1111","holder":"D. Havelock","balance":"82914.55"}

الشيء الوحيد الذي يتغيّر هو كيفية كتابة المتحكّم للاستجابة.

النتائج المقاسة

BASELINE  standard Spring MVC return value
  /safe/account                    OK        all 6 headers delivered

CONTROL   getOutputStream(), body > 8 KB buffer
  /vuln/stream/account             OK        all 6 headers delivered

CONTROL   explicit response.flushBuffer()
  /vuln/flush/account              OK        all 6 headers delivered

EXPLOIT   setIntHeader("Content-Length", n)  <-- CVE-2026-22732
  /vuln/content-length/account     BYPASSED  ALL 6 security headers dropped

BY DESIGN application sets its own Expires header (NOT this CVE)
  /vuln/cache/account              PARTIAL   Cache-Control + Pragma dropped

فقط /vuln/content-length/account تتغيّر حالته عند ترقيع CVE، لذا فهو نقطة النهاية الوحيدة التي يستمدّ منها exploit.sh حكمه. والباقي عناصر تحكّم.

الثغرة — setIntHeader("Content-Length", n) → تجاوز كامل

ثلاثة أسطر من كود متحكّم يبدو عاديًا تجرّد كل رأس وعد به Spring Security:

response.setContentType("application/json");
response.setIntHeader("Content-Length", body.length);
response.getOutputStream().write(body);
$ curl -sD - -o /dev/null http://localhost:8080/vuln/content-length/account
HTTP/1.1 200
Content-Type: application/json
Content-Length: 77
Date: Tue, 01 Sep 2026 00:53:18 GMT

لا X-Frame-Options، لا X-Content-Type-Options، لا Cache-Control، لا Pragma، لا Expires، لا X-XSS-Protection. قارن مع /safe/account، الذي يحمل الستة جميعًا. الاستجابة قابلة للتأطير من أي أصل، وقابلة لاستنشاق MIME، وقابلة للتخزين المؤقت — بينما تخدم رقم بطاقة.

الحالة بحكم التصميم — رأس تخزين مؤقت يضبطه التطبيق → كبت التخزين المؤقت

تصحيح: نسخة سابقة من هذا README سمّت هذه "الاستغلال 2" وادّعت أنها الحالة التي توثّقها النشرة. هي ليست جزءًا من CVE-2026-22732 ولا يصلحها أي ترقية. CacheControlHeadersWriter متطابق بايت ببايت في 5.7.11 و5.7.14-0.cgr.2 و6.5.8 (آخر إصدار مصاب) و 6.5.9 (أول إصدار مُصلَّح) — تم التحقق بمقارنة ملفات المصادر jars. يذكر توثيقها Javadoc السلوك صراحةً: "Inserts headers to prevent caching if no cache control headers have been specified."

لا يزال يستحق العرض، لأن التسريب حقيقي والمخاطر المتبقية تنجو من الترقيع. يتوقف CacheControlHeadersWriter إذا كان Cache-Control أو Expires أو Pragma موجودًا بالفعل، لذا فإن ضبط أي واحد من الثلاثة يكبت كل توجيهات no-store الخاصة بـ Spring Security. سطر واحد حسن النية يفعل ذلك:

response.setHeader("Expires", "Thu, 01 Jan 2099 00:00:00 GMT");
/safe/account                  NOT cacheable  (Cache-Control: no-cache, no-store, max-age=0, must-revalidate)
/vuln/cache/account            CACHEABLE      (Cache-Control: absent / Expires: Thu, 01 Jan 2099 00:00:00 GMT)
/vuln/content-length/account   CACHEABLE      (Cache-Control: absent / Expires absent)

يُحتسب Expires كـ"موجود" في الجدول أعلاه، لكن بقيمة صديقة للمهاجم اختارها التطبيق — تم استبدال Expires: 0 الخاص بـ Spring Security، لا مجرد إسقاطه. بيانات حامل البطاقة الآن قابلة للتخزين من كل متصفح ووكيل مشترك على المسار حتى 2099.

على البناء المُرقَّع يتحوّل /vuln/content-length/account إلى NOT cacheable، بينما يبقى /vuln/cache/account تمامًا كما هو أعلاه. فقط كود التطبيق أو وكيل عكسي يصلحه — وهذا هو الشيء المفيد قوله بصوت عالٍ في عرض: ترقية المكتبة تغلق CVE وتترك هذا دون مساس.

نتيجتان سلبيتان، محفوظتان عن قصد

عدة مقالات متداولة على نطاق واسع — بما في ذلك مستودع إعادة إنتاج عام — تُدرج response.getOutputStream() وresponse.flushBuffer() كمحفّزات، موضّحة أن "الاستجابة تُثبَّت قبل أن يتمكن Spring Security من حقن رؤوسه". على Spring Security 5.7.11 هذا خطأ. كلتا نقطتي النهاية تُسلّمان الرؤوس الستة جميعًا.

يُظهر /diag/committed لماذا لا يصمد التفسير. بعد كتابة 12 KB تكون الاستجابة فعلًا مثبَّتة داخل المتحكّم، ومع ذلك تصل الرؤوس:

>>> DIAG response.isCommitted() after 12048 byte write = true
    | wrapper class = org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterResponse

يتجاوز OnCommittedResponseWrapper الدالة flushBuffer() وكتابات تدفق الإخراج، لذا يُخرج رؤوسه قبل تلك التثبيتات. ترتيب التثبيت وحده ليس العلّة؛ مسار Content-Length المُعلَن هو العلّة. نشرة Spring نفسها لا تؤيد أبدًا رواية ترتيب التثبيت.

إبقاء نقطتي النهاية هاتين يجعل PoC قابلًا للتكذيب: يُظهر ما لا يُعاد إنتاجه بوضوح كما يُظهر ما يُعاد إنتاجه، وكلاهما يبقى أخضر عبر الترقيع، وهو ما يجعل نقطة النهاية الوحيدة التي تنقلب ذات معنى.

الانتقال من المصاب → المُرقَّع

سطر واحد في pom.xml، لا شيء آخر. لا تغيير في المصدر، لا تغيير في الخاصية، لا ترقية إصدار رئيسي لـ Spring Boot:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.7.18</version>            <!-- vulnerable -->
  <version>2.7.18-0.cgr.3</version>    <!-- patched   -->
</parent>

هذا يعيد تثبيت spring-security.version من 5.7.11 إلى 5.7.14-0.cgr.2 (و spring-framework.version من 5.3.31 إلى 5.3.39-0.cgr.4) عبر spring-boot-dependencies الخاص بالوالد. القياس:

2.7.182.7.18-0.cgr.3
/safe/accountOK 6/6OK 6/6
/vuln/stream/accountOK 6/6OK 6/6
/vuln/flush/accountOK 6/6OK 6/6
/vuln/content-length/accountBYPASSED 0/6OK 6/6
/vuln/cache/accountPARTIAL 4/6PARTIAL 4/6 (by design)
exploit.sh verdictVULNERABLEPATCHED

النقل العكسي هو الإصلاح الرسمي

بمقارنة ملفات المصادر jars الخاصة بـ spring-security-web، ملف واحد فقط يهم. 5.7.11 → 5.7.14-0.cgr.2 يضيف تجاوزات setHeader / setIntHeader / addIntHeader إلى OnCommittedResponseWrapper، كل منها يوجّه Content-Length عبر setContentLength():

تنزيل الأداة