
إصلاح فوري لـ CVE-2023-29689 - ثغرة SSTI في PyroCMS، عبر تطبيق صندوق حماية Twig مخصص
إصلاح أمني فوري لـ CVE-2023-29689 - حقن القوالب من جانب الخادم (SSTI) يؤدي إلى تنفيذ الأوامر عن بعد (RCE) في PyroCMS 3.9.
يسمح PyroCMS للمستخدمين الإداريين بتحرير القوالب المخزنة في قاعدة البيانات. بدون آلية عزل (Sandboxing)، يمكن للمهاجمين الذين لديهم صلاحيات إدارية حقن كود Twig ضار:
{{['id']|map('system')|join}}
يقوم هذا بتنفيذ أوامر النظام التعسفية. يعتبر المطورون الأساسيون هذا "يعمل كما هو مقصود" نظرًا لأن المستخدمين الإداريين موثوق بهم - ولكن في بيئات متعددة المستأجرين أو المؤسسات، "المسؤول" لا يعني "موثوق به مع الوصول إلى الصدفة".
تقوم هذه الحزمة تلقائيًا بعزل القوالب القابلة للتحرير من قبل المستخدم مع ترك قوالب السمات/الإضافات المشروعة دون قيود. تستخدم واجهة SourcePolicyInterface من Twig (التي ساهم بها مؤلف هذه الحزمة في المصدر الأصلي) لتطبيق القيود بشكل انتقائي.
composer require ysaxon/pyrocms-ssti-fix
للأسف، نظرًا لتعطيل PyroCMS للاكتشاف التلقائي (autodiscovery) كما في هذا الالتزام، ستحتاج إلى إضافة مزود الخدمة (serviceProvider) بنفسك.
يمكنك القيام بذلك باستخدام:
sed -i "/App\\\Providers\\\AppServiceProvider::class,/a \ YSaxon\\\PyroCmsSstiFix\\\SandboxServiceProvider::class," config/app.php
SourcePolicyInterface)┌─────────────────────────────────────────────────────────────┐
│ طلب عرض القالب (Twig Render) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ StorageSourcePolicy │
│ │
│ هل القالب من مسار التخزين (قاعدة بيانات/قابل للتحرير)؟ │
│ │
│ نعم ──────────────────► تفعيل صندوق العزل │
│ │ - منع: map, filter, reduce │
│ │ - منع: الوسوم الخطرة │
│ │ - السماح بالعمليات الآمنة │
│ │
│ لا ───────────────────► بدون عزل │
│ (قوالب السمات/الإضافات تعمل │
│ بشكل طبيعي) │
└─────────────────────────────────────────────────────────────┘
الإعدادات الافتراضية آمنة وتعمل مع معظم التثبيتات. للتخصيص:
php artisan vendor:publish --tag=pyrocms-ssti-fix-config
ينشئ هذا ملف config/pyrocms-ssti-fix.php:
return [
// مفتاح التشغيل الرئيسي
'enabled' => env('PYROCMS_SSTI_FIX_ENABLED', true),
// تجاوز مسار التخزين المكتشف تلقائيًا
'storage_path' => env('PYROCMS_SSTI_FIX_STORAGE_PATH', null),
// تخصيص الوسوم/المرشحات/الدوال/الطرق/الخصائص المسموح بها
'policy' => [
'tags' => [SecurityPolicyDefaults::INCLUDE_DEFAULTS],
'filters' => [SecurityPolicyDefaults::INCLUDE_DEFAULTS],
// ... راجع ملف الإعدادات للخيارات الكاملة
],
];
تقوم سياسة الأمان الافتراضية بحظر هذه الميزات الخطيرة في القوالب المعزولة:
map - {{['cmd']|map('system')}} تنفيذ أوامر الصدفةfilter - يمكن استدعاء دوال PHP تعسفيةreduce - يمكن استدعاء دوال PHP تعسفيةinclude, extends, block, macro, import, embed, usesource - قراءة محتويات ملفات تعسفيةinclude - تضمين قوالب أخرىtemplate_from_string - إنشاء قوالب من سلاسل نصيةتبقى العمليات الآمنة متاحة في القوالب المعزولة:
{# المتغيرات #}
{{ entry.title }}
{{ user.name|upper }}
{# الحلقات والشروط #}
{% for item in items %}
{% if item.active %}
{{ item.name }}
{% endif %}
{% endfor %}
{# المرشحات الآمنة #}
{{ text|escape }}
{{ date|date('Y-m-d') }}
{{ items|length }}
{{ name|lower|trim }}
{# الدوال الآمنة #}
{{ max(a, b) }}
{{ random(['red', 'blue', 'green']) }}
إذا كانت قوالب الإدارة تحتاج بشكل مشروع إلى ميزات إضافية:
// config/pyrocms-ssti-fix.php
'policy' => [
'filters' => [
SecurityPolicyDefaults::INCLUDE_DEFAULTS,
'my_custom_filter', // إضافة مرشح معين
],
'methods' => [
SecurityPolicyDefaults::INCLUDE_DEFAULTS,
'App\Models\Post' => ['getTitle', 'getSummary'],
],
],
بعد التثبيت، تحقق من منع الاستغلال:
{{['id']|map('system')|join}}قبل الإصلاح: يظهر مخرجات أمر id (أو يتعطل)
بعد الإصلاح: يظهر خطأ أو رسالة: [rendering failed: Filter "map" is not allowed.]
لم تتمكن الحزمة من العثور على Twig. هذا يعني عادةً:
قم بتمكين وضع التصحيح لرؤية التفاصيل:
PYROCMS_SSTI_FIX_DEBUG=true
إذا كانت القوالب القابلة للتحرير من قبل المسؤول تستخدم ميزات أصبحت محظورة الآن:
تقوم الحزمة بتخزين جميع فحوصات المسار وعمليات البحث عن الطرق/الخصائص مؤقتًا. في الوضع auto، only templates in storage-path incur sandbox overhead.
SourcePolicyInterface في Twigرخصة MIT - راجع ملف LICENSE.