
سجل وعرض تقديمي حول التحقق من ثغرة الكتابة خارج النطاق CVE-2026-14662 المكتشفة في بحث PostgreSQL النصي الكامل (tsvector/tsquery)، عبر تشغيل الإصدارات قبل الإصلاح (18.4) وبعد الإصلاح (18.6) جنبًا إلى جنب باستخدام Docker.
هذا سجل لملاحظة الفرق الفعلي في السلوك بين الإصدار قبل التصحيح (18.4) والإصدار بعد التصحيح (18.6) من PostgreSQL، من خلال تشغيلهما معًا في Docker، وذلك بشأن
CVE-2026-14662 المكتشفة في أنواع بيانات البحث النصي الكامل (tsvector / tsquery).
تم إعداده لأغراض التعلم الأمني، ويتضمن أيضًا مواد العرض التقديمي.
| البند | المحتوى |
|---|
| CVE | CVE-2026-14662 |
| الهدف | tsvector / tsquery في PostgreSQL |
| النوع | نقص حجم التخصيص بسبب التفاف الأعداد الصحيحة وكتابة خارج النطاق |
| CVSS | 8.8 / 10.0 (عالية) |
| تاريخ النشر | 2026-08-13 |
| الإصدارات المصححة | 18.5، 17.11، 16.15، 15.19، 14.24 |
تسلسل نقاط الضعف يكون على الشكل التالي.
CWE-190 (فيضان الأعداد الصحيحة) ← CWE-131 (حساب خاطئ لحجم المخزن المؤقت) ← CWE-787 (كتابة خارج النطاق)
=السبب الجذري =التأثير النهائي
.
├── docs/
│ └── presentation.md مواد العرض التقديمي (شرح الثغرة + شرح CWE)
└── docker/
├── README.md طريقة استخدام بيئة إعادة الإنتاج
├── docker-compose.yml
├── init/ SQL تهيئة مشترك يُنفَّذ على كلا الإصدارين
├── test/ PoC و SQL للعرض التوضيحي
└── run.sh التشغيل ← تنفيذ PoC ← عرض النتائج
إذا كان لديك Docker و Docker Compose، يمكنك إعادة الإنتاج فقط بما يلي.
cd docker
./run.sh
سيتم تشغيل حاويتي 18.4 و 18.6، وبعد إدخال نفس SQL التهيئة، سيتم تنفيذ نفس PoC على كليهما وعرض النتائج جنبًا إلى جنب. راجع docker/README.md للحصول على التفاصيل.
| الاختبار | PostgreSQL 18.4 (قبل التصحيح) | PostgreSQL 18.6 (بعد التصحيح) |
|---|---|---|
| تكرار الدمج الذاتي OR لـ tsquery | نجاح بدون أي خطأ حتى 18 مرة (النهائي 8,650,748 بايت) | في المرة 17: ERROR: tsquery is too large |
| مصفوفة كلمات بطول إجمالي 1,200,000 بايت | ينجح بشكل خاطئ | ERROR: string is too long for tsvector (1200000 bytes, max 1048575 bytes) |
| كلمة واحدة بحجم 3,000 بايت | ينجح بشكل خاطئ | ERROR: word is too long (3000 bytes, max 2046 bytes) |
قبل التصحيح، يتم قبول البيانات التي تتجاوز الحد الأقصى للتمثيل الداخلي (MAXSTRPOS = 1,048,575 المشتق من حقل بت 20-بت)
دون إصدار أي خطأ.
لاحظ أن سبب توقف 18.6 عند "المرة 17 بالضبط" يمكن تفسيره حسابيًا، وقد تأكدنا من تطابق القيمة النظرية مع القيمة المقاسة بالبايت (التفاصيل في مواد العرض).
للتحقق من الفروقات، استخدمنا استنساخًا للمستودع الرسمي لـ PostgreSQL، ولكن نظرًا لكبر حجمه (185MB لكل منهما)، لم يتم تضمينه في هذا المستودع. إذا لزم الأمر، قم بالحصول عليه كما يلي.
git clone --branch REL_18_4 --depth 1 https://github.com/postgres/postgres.git postgres-18.4
git clone --branch REL_18_6 --depth 1 https://github.com/postgres/postgres.git postgres-18.6
الملفات التي تم تعديلها هي الثلاثة التالية.
src/backend/utils/adt/tsquery_util.csrc/backend/utils/adt/tsvector.csrc/backend/utils/adt/tsvector_op.c