
Docker-лаборатория, демонстрирующая обход пути CVE-2026-12243 в NLTK до версии 3.10.0, сравнивающая уязвимое и исправленное поведение с синтетическим секретом в изолированной автономной среде.
Небольшая воспроизводимая Docker-лаборатория, которая сравнивает поведение percent-encoded path traversal в NLTK 3.9.4 с исправленным поведением в NLTK 3.10.0.
Уязвимая версия проверяет имя ресурса до декодирования URL. Исправленный
payload %2e%2e/%2e%2e/outside/lab-secret.txt проходит проверку, затем
декодируется в ../../outside/lab-secret.txt и выходит за пределы как
настроенного каталога данных NLTK, так и рабочего каталога процесса. Исправленная
версия отклоняет тот же самый ввод.
[!CAUTION] Этот репозиторий предназначен только для оборонительного обучения и авторизованного тестирования. Лаборатория использует фиксированный синтетический секрет внутри изолированного контейнера. Не адаптируйте её для доступа к системам или данным, которыми вы не владеете или на тестирование которых у вас нет явного разрешения.
| Контейнер | Версия NLTK | Ожидаемый результат |
|---|---|---|
vulnerable | 3.9.4 | Читает синтетический маркер за пределами /lab/nltk_data |
patched |
Загрузка корпуса, сервер, порт, bind mount или интернет-соединение во время выполнения не используются.
docker compose)run.shgit clone https://github.com/morzelowski/CVE-2026-12243-NLTK-PoC.git
cd CVE-2026-12243-NLTK-PoC
docker compose build
./run.sh
Ожидаемый результат:
=== Vulnerable image: NLTK 3.9.4 ===
NLTK version : 3.9.4
Working directory : /app
Configured data dir: /lab/nltk_data
Encoded resource : %2e%2e/%2e%2e/outside/lab-secret.txt
Decoded resource : ../../outside/lab-secret.txt
Resolved candidate : /outside/lab-secret.txt
NLTK warning : Security Violation [pathsec.open]: Unauthorized path /outside/lab-secret.txt
NLTK result : read 36 bytes
Synthetic marker : CVE-2026-12243-SYNTHETIC-LAB-MARKER
[PASS] Traversal escaped the configured NLTK data directory.
=== Patched image: NLTK 3.10.0 ===
NLTK version : 3.10.0
NLTK result : blocked (ValueError: Unsafe resource path: '...')
[PASS] Patched version rejected the same encoded traversal.
Lab completed: traversal reproduced and patched rejection verified.
Затронутый образ сообщает, что /outside/lab-secret.txt не авторизован, но
всё равно возвращает его содержимое, поскольку NLTK 3.9.4 по умолчанию использует
безопасность путей только с предупреждениями. Текст исключений и предупреждений
может незначительно отличаться; run.sh использует код завершения процесса,
а не хрупкое сравнение текста, чтобы определить, прошла ли демонстрация.
Каждый образ содержит следующую намеренно разделённую структуру:
/
├── app/
│ └── poc.py # рабочий каталог процесса — /app
├── lab/
│ └── nltk_data/ # настроенный корень поиска NLTK
└── outside/
└── lab-secret.txt # публичный синтетический маркер
poc.py заменяет nltk.data.path на /lab/nltk_data и передаёт фиксированное
имя ресурса %2e%2e/%2e%2e/outside/lab-secret.txt в
nltk.data.load(..., format="raw"). В затронутой версии декодирование
происходит слишком поздно в процессе проверки:
/lab/nltk_data
↓ ../../outside/lab-secret.txt
/outside/lab-secret.txt
Поскольку рабочий каталог — /app, канарейка находится за пределами обоих
мест, которые имеют значение для демонстрации: /app и /lab/nltk_data.
Скрипт содержит два явных утверждения:
Любой другой результат завершается с ненулевым кодом, поэтому автоматические проверки не могут сообщить о ложном успехе.
Конфигурация Compose намеренно ограничивает лабораторию:
network_mode: none отключает сеть во время выполнения любой из демонстраций.no-new-privileges.noexec.fixtures/lab-secret.txt, публичный
тестовый маркер, копируемый в образ во время сборки.Для сборки образа требуется доступ к индексу пакетов для установки двух зафиксированных версий NLTK. Выполнение во время работы происходит офлайн.
nltk.data.load()
или nltk.data.find()Лаборатория фиксирует версию 3.9.4, поскольку это конкретный релиз, указанный в исходном отчёте, и 3.10.0, поскольку это первый исправленный релиз, зафиксированный в рекомендации мейнтейнера.
Обновите NLTK и поддерживайте его в актуальном состоянии:
python -m pip install "nltk>=3.10.0"
Также избегайте передачи недоверенных имён ресурсов в API загрузки из файловой системы. Если требуется выбор пользователя, сопоставляйте пользовательские идентификаторы с белым списком ресурсов, принадлежащих приложению, вместо прямого принятия путей или URL.
Запустите любую из сторон независимо:
docker compose run --rm vulnerable
docker compose run --rm patched
Просмотрите полностью разрешённую конфигурацию Compose:
docker compose config
Удалите локально собранные образы лаборатории:
docker compose down --rmi local
permission denied: ./run.sh — выполните chmod +x run.sh один раз.docker: command not found — установите Docker Desktop или Docker Engine.docker compose build --no-cache.aec4fceВыпущено под лицензией MIT.
3.10.0| Блокирует закодированный обход |