
يوثّق سلسلة RCE من نوع use-after-free في VectorFreed librsvg (CVE-2026-96889) مع PoC لمولّد SVG وإرشادات المعالجة لـ librsvg وNext.js وSatori.
تقدم هذه الوثيقة "VectorFreed"، وهي سلسلة ثغرات تبدأ بثغرة use-after-free اكتشفتها أنا (@rafabd1) في librsvg (CVE-2026-96889). في بناء Node.js/Sharp/libvips، أدت هذه الثغرة إلى تنفيذ أوامر. وتغطي الوثيقة الثغرة، والمسارات المؤكدة في التطبيقات حتى الآن، والإصلاحات المتاحة الآن.
يمكن لملف SVG أن يتضمن ملف SVG آخر عبر XInclude. في المسار المصاب، يبدأ librsvg في تحليل مستند مُضمَّن بينما لا يزال libxml2 يوسّع كيانًا في المستند الخارجي. إذا أعلن ملف SVG المُضمَّن عن كيان يحمل الاسم نفسه، يستبدل librsvg الكيان الأول ويحرر ذاكرته. لكن libxml2 لا يزال يحتفظ بمؤشر إليه.
عندما ينتهي تحليل المستند المُضمَّن، يواصل libxml2 باستخدام ذلك المؤشر القديم. وقد تكون الذاكرة مملوكة لشيء آخر بحلول ذلك الوقت، لذا يمكن أن تؤدي الكتابات اللاحقة إلى إفسادها. الانهيار هو إحدى النتائج. وفي حالات أخرى، أدى هذا أيضًا إلى تنفيذ أوامر.
يحتاج المهاجم إلى ترميز SVG مُصمَّم بعناية للوصول إلى librsvg. يمكن أن يحدث ذلك عندما يقبل تطبيق ما ملف SVG، لكنه يمكن أن يحدث أيضًا عندما يبني التطبيق ملف SVG من مدخلات المستخدم. مجرد استخدام librsvg في مكان ما ضمن شجرة التبعيات لا يثبت وجود مسار قابل للاستغلال؛ يجب أن يصل المُدخل إلى بناء مصاب عند عرض الصورة.
مسار Next.js الذي اختبرناه كان يقبل نصًا بدلًا من رفع ملف SVG. وقد وضع ذلك النص داخل SVG مضمّن لنسخة Node.js من ImageResponse. سمحت ثغرة تهريب منفصلة في Satori للنص بتغيير ترميز SVG المُولَّد. ثم مرّر Sharp/libvips ذلك SVG إلى librsvg. وقد تتبعت Vercel مسار Next.js بوصفه CVE-2026-94545. نسخة Edge من ImageResponse غير متأثرة بهذا المسار. إليك إعادة إنتاج قصيرة لـ Next.js.
خلال هذا البحث، حددت مسارات إدخال مصابة في عدة منتجات تابعة، وأكدت تنفيذ أوامر في عدد منها، بما في ذلك حالة Next.js الموصوفة أعلاه. تختلف طريقة وصول ذلك المُدخل إلى librsvg من منتج لآخر. ولهذا السبب يمكن أن تظهر ثغرة في محلل صور في المنبع في أماكن لا تبدو ذات صلة للوهلة الأولى؛ وحالة libheif الأخيرة مثال آخر. وهذا لا يعني أن كل منتج يستخدم librsvg قابل للاستغلال عن بُعد.
ImageResponse في Node.js. قم بالترقية إلى 16.3.6.إذا كنت تستخدم الملفات الثنائية المُعدّة مسبقًا من Sharp، فتحقق من حزمة @img/sharp-libvips-* التي ثبّتها تطبيقك. فهي تضم libvips وتبعياته، بما في ذلك librsvg. قد يؤدي تحديث نسخة النظام من librsvg إلى ترك تطبيقك يستخدم النسخة القديمة.
يتضمن UAF PoC مولّد SVG لعدة مسارات إدخال، ويمكن استخدامه للتحقق من ثغرة use-after-free في بداية السلسلة.
حتى الآن، لم أجد استغلالًا عامًا يأخذ هذه السلسلة بالكامل من SVG مُصمَّم إلى تنفيذ أوامر. لكن الثغرة والتصحيحات أصبحت عامة بالفعل، ومع أدوات الذكاء الاصطناعي الحالية أصبح من السهل نسبيًا العمل بشكل عكسي للوصول إلى السلسلة الكاملة انطلاقًا منها. وبالنظر إلى ذلك، تعامل مع الاستغلال كما لو كان عامًا بالفعل، وحدّث التبعيات المتأثرة أو خفف مسار الإدخال في أقرب وقت ممكن.
[!WARNING] لا يوجد PoC عام لتنفيذ الأوامر عن بُعد (RCE) لهذه السلسلة؛ يجب تعديل الحمولة لكل هدف. معظم "إثباتات المفهوم" العامة التي رأيتها حتى الآن لا تعيد إنتاج سلسلة RCE الفعلية. يعتمد بعضها على SVG
<foreignObject>للتنفيذ المزعوم، وهو ليس مسار الاستغلال الموصوف هنا.
للتحقق الأولي، يعد UAF PoC أكثر عملية. أخطط لنشر PoC لتنفيذ الأوامر عن بُعد (RCE) لحالة Next.js (CVE-2026-94545) في مستودع منفصل. سأنشر أيضًا التحليل التقني في الأسابيع المقبلة، مع الخطوات من UAF إلى تنفيذ الأوامر، وتشريح لما بعد الحادث يغطي هذا الشهر الماضي من البحث في السلسلة.