Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-12243-NLTK-PoC — Docker lab demonstrating CVE-2026-12243 path traversal in NLTK before 3.10.0, contrasting vulnerable and patched behavior with a synthetic secret in an isolated, offline environment. | Kitploit
Tools/GitHubGitHub/morzelowski/cve-2026-12243-nltk-poc
Container SecurityVulnerability AnalysisWeb SecurityLearning & EducationLabs & Practice
GitHubmorzelowski/cve-2026-12243-nltk-poc

CVE-2026-12243-NLTK-PoC

Docker lab demonstrating CVE-2026-12243 path traversal in NLTK before 3.10.0, contrasting vulnerable and patched behavior with a synthetic secret in an isolated, offline environment.

View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
9h 25m agoNot yet reviewed

CVE-2026-12243 — NLTK Path Traversal Lab

CVE NLTK Lab License

A small, reproducible Docker lab that contrasts the percent-encoded path traversal behavior in NLTK 3.9.4 with the corrected behavior in NLTK 3.10.0.

The vulnerable version validates the resource name before URL decoding. The fixed payload %2e%2e/%2e%2e/outside/lab-secret.txt passes the check, is later decoded to ../../outside/lab-secret.txt, and escapes both the configured NLTK data directory and the process working directory. The patched version rejects the same input.

[!CAUTION] This repository is for defensive education and authorized testing only. The lab uses a fixed synthetic secret inside an isolated container. Do not adapt it to access systems or data you do not own or have explicit permission to test.

At a glance

ContainerNLTK versionExpected result
vulnerable3.9.4Reads the synthetic marker outside /lab/nltk_data
patched

No corpus download, server, port, bind mount, or runtime internet connection is used.

Prerequisites

  • Docker Engine or Docker Desktop
  • Docker Compose v2 (docker compose)
  • A POSIX shell for run.sh

Usage

root@kitploit:~
git clone https://github.com/morzelowski/CVE-2026-12243-NLTK-PoC.git
cd CVE-2026-12243-NLTK-PoC
docker compose build
./run.sh

Expected result:

root@kitploit:~
=== 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.

The affected image reports that /outside/lab-secret.txt is unauthorized but still returns its contents because NLTK 3.9.4 uses warning-only path security by default. Exception and warning text can vary slightly; run.sh uses the process exit status, not a fragile text match, to decide whether the demonstration passed.

How the demonstration works

Each image contains this deliberately separated layout:

root@kitploit:~
/
├── app/
│   └── poc.py          # process CWD is /app
├── lab/
│   └── nltk_data/      # configured NLTK search root
└── outside/
    └── lab-secret.txt  # public synthetic marker

poc.py replaces nltk.data.path with /lab/nltk_data and passes the fixed resource name %2e%2e/%2e%2e/outside/lab-secret.txt to nltk.data.load(..., format="raw"). In the affected release, decoding occurs too late in the validation flow:

root@kitploit:~
/lab/nltk_data
      ↓  ../../outside/lab-secret.txt
/outside/lab-secret.txt

Because the working directory is /app, the canary is outside both locations that matter to the demonstration: /app and /lab/nltk_data.

The script has two explicit assertions:

  1. NLTK 3.9.4 must return the known synthetic marker.
  2. NLTK 3.10.0 must reject the exact same resource name.

Any other result exits non-zero, so automated checks cannot report a false success.

Safety model

The Compose configuration intentionally limits the lab:

  • network_mode: none disables networking while either demonstration runs.
  • No host ports are published.
  • No host directories or Docker socket are mounted.
  • The containers run as an unprivileged user with all Linux capabilities dropped and no-new-privileges enabled.
  • The root filesystem is read-only; only a small, noexec temporary filesystem is writable.
  • The only disclosed value is fixtures/lab-secret.txt, a public test marker copied into the image during build.

The image build needs package-index access to install the two pinned NLTK versions. Runtime execution is offline.

Technical details

  • CVE: CVE-2026-12243
  • GHSA: GHSA-m42h-3232-vpv3
  • Weakness: CWE-22 — path traversal
  • Affected: NLTK versions before 3.10.0
  • Fixed: NLTK 3.10.0
  • Impact: disclosure of files readable by the application process when an attacker controls a resource name supplied to nltk.data.load() or nltk.data.find()

The lab pins 3.9.4 because it is the concrete release named in the original report and 3.10.0 because it is the first patched release recorded by the maintainer advisory.

Mitigation

Upgrade NLTK and keep it current:

root@kitploit:~
python -m pip install "nltk>=3.10.0"

Also avoid passing untrusted resource names into filesystem-loading APIs. Where user selection is required, map user-facing identifiers to an allowlist of application-owned resources instead of accepting paths or URLs directly.

Manual commands

Run either side independently:

root@kitploit:~
docker compose run --rm vulnerable
docker compose run --rm patched

Inspect the fully resolved Compose configuration:

root@kitploit:~
docker compose config

Remove the locally built lab images:

root@kitploit:~
docker compose down --rmi local

Troubleshooting

  • permission denied: ./run.sh — run chmod +x run.sh once.
  • docker: command not found — install Docker Desktop or Docker Engine.
  • Package download errors during build — confirm Docker has temporary outbound access for the build, then retry docker compose build --no-cache.

References

  • GitHub maintainer advisory GHSA-m42h-3232-vpv3
  • NVD entry for CVE-2026-12243
  • Original NLTK issue #3504
  • NLTK fix pull request #3522
  • Fix commit aec4fce

License

Released under the MIT License.

Download Tool
3.10.0
Blocks the encoded traversal