Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
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
Tools/GitHubGitHub/jithinodattu/cve-2007-4559-lab
Static AnalysisVulnerability AnalysisCode AnalysisWeb Application ExploitationCTFSupply Chain SecurityLearning & EducationBinary ExploitationLabs & Practice
GitHubjithinodattu/cve-2007-4559-lab

CVE-2007-4559-lab

Self-contained Docker lab demonstrating CVE-2007-4559 (TarSlip) directory traversal via Python's tarfile module. Includes vulnerable and fixed APIs, payload generation, and an interactive demo script for security education.

View Repository
155 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2007-4559 — TarSlip: The 15-Year Directory Traversal

Educational use only. This lab intentionally exploits file system vulnerabilities inside isolated Docker containers. Do not run on any system with sensitive data or in production environments.

A self-contained Docker lab that demonstrates CVE-2007-4559 — the infamous "TarSlip" vulnerability in Python's tarfile module — through a concrete, end-to-end attack chain:

  1. An attacker uploads a crafted tarball to a file upload API.
  2. extractall() blindly writes a tar entry named ../../../etc/passwd outside the extraction directory, overwriting the real system file.
  3. The planted password grants the attacker access to a protected /admin endpoint.
  4. The same attack is then run against a fixed API — and blocked with one line of code.

The vulnerability

Python's tarfile.extractall() faithfully reproduces every entry in a tar archive, including entries whose names contain ../ path traversal sequences. It was never designed to be a security boundary.

tar entry name : ../../../etc/passwd
extraction dir : /shared/uploads/a1b2c3d4/

resolved path  : /shared/uploads/a1b2c3d4/../../../etc/passwd
               = /etc/passwd   ← system file overwritten
Timeline
2007Bug reported to the Python security team
2007 – 2022Marked "not a security issue" — tarfile is "working as intended"
2022Trellix researchers scan GitHub and find 350,000+ repos calling extractall() on untrusted input
2022Public disclosure. CVE-2007-4559 resurfaces. Industry-wide scramble.
2023PEP 706 ships filter='data' in Python 3.12 — the fix is a single argument

What the demo shows

The demo runs in three beats, each requiring a keypress to advance.

Beat 1 — Baseline

  • GET /admin → 401. The admin endpoint exists and is protected. The attacker does not know the password.
  • Upload innocent.tar.gz → files land inside the sandbox directory. Everything looks normal.

Beat 2 — The Exploit

Attacker crafts tarslip_passwd.tar.gz
  └─ entry: "../../../etc/passwd"
       content: admin:hacked:1001:...   ← planted password
            │
            ▼
  POST /upload  (multipart file upload)
            │
            ▼
  extractall("/shared/uploads/{uuid}/")
  resolves "../../../etc/passwd" → /etc/passwd   ← CVE-2007-4559
            │
            ▼
  GET /admin   Authorization: Basic admin:hacked
            │
            ▼
  HTTP 200 — "Welcome, admin! You have full admin access."
  flag: CVE-2007-4559{tarslip_passwd_overwrite_to_admin_rce}

One HTTP POST. No shell. No RCE payload. Just a tar file.

Beat 3 — The Fix

The same tarball is uploaded to the fixed API, which passes filter='data' to extractall(). Python raises tarfile.OutsideDestinationError — the traversal is blocked, /etc/passwd is untouched, and /admin stays locked.

# Vulnerable — default before Python 3.14
tar.extractall(extraction_dir)

# Fixed — PEP 706 (Python 3.12+)
tar.extractall(extraction_dir, filter='data')

One argument. Fifteen years to ship.


Architecture

Four services on an isolated Docker bridge network (tarslip-net). Nothing reaches the internet.

┌─────────────────────────────────────────────────────────┐
│                    tarslip-net (bridge)                  │
│                                                          │
│  ┌─────────────────┐      ┌──────────────────────────┐  │
│  │  vulnerable-api │      │       file-server        │  │
│  │  python:3.11.3  │      │       nginx:alpine       │  │
│  │  port 8000      │      │       port 8080 (host)   │  │
│  │                 │      │                          │  │
│  │  POST /upload   │      │  Serves /shared over     │  │
│  │  GET  /admin    │      │  HTTP — browse extracts  │  │
│  │  GET  /health   │      │  visually                │  │
│  └────────┬────────┘      └────────────┬─────────────┘  │
│           │  shared-storage volume     │                 │
│           └────────────────────────────┘                 │
│                                                          │
│  ┌─────────────────┐                                     │
│  │    attacker     │                                     │
│  │  python:3.12    │  (no host port — internal only)     │
│  │                 │                                     │
│  │  craft_malicious.py  — generates tarballs             │
│  │  demo.py             — drives the demo                │
│  └─────────────────┘                                     │
└─────────────────────────────────────────────────────────┘
ServiceImageRoleHost port
vulnerable-apipython:3.11.3-slimFlask upload API + /admin guarded by /etc/passwd auth8000
fixed-apipython:3.12-slimSame code + USE_SAFE_EXTRACTION=true8000
file-servernginx:alpineDirectory listing of extracted files8080
attackerpython:3.12-slimPayload generator + demo driver—

The vulnerable and fixed APIs use identical source code. The only difference is the USE_SAFE_EXTRACTION=true environment variable on the fixed container, which flips the single filter='data' argument.


Repository layout

CVE-2007-4559-lab/
├── run_demo.sh                      ← start here
├── docker-compose.vulnerable.yml
├── docker-compose.fixed.yml
├── vulnerable-api/
│   ├── app.py                       # Flask API: /upload + /admin + /health
│   ├── Dockerfile                   # seeds admin:s3cr3t_Adm1nPass into /etc/passwd
│   └── requirements.txt
├── file-server/
│   ├── Dockerfile
│   └── nginx.conf
└── attacker/
    ├── craft_malicious.py           # generates innocent.tar.gz + tarslip_passwd.tar.gz
    ├── demo.py                      # four-mode CLI driver (craft/baseline/exploit/verify)
    ├── Dockerfile
    └── requirements.txt

Prerequisites

  • Docker 20.10+ with the Compose plugin (docker compose version)
  • macOS / Linux — the shell script uses bash
  • Ports 8000 and 8080 free on your host

Running the demo

git clone https://github.com/your-username/CVE-2007-4559-lab.git
cd CVE-2007-4559-lab
bash run_demo.sh

The script is fully interactive. It prints a narrative before each step and waits for Enter to advance. No prior Docker knowledge is needed to follow along.

What each pause point covers

PauseNarrative shownAction on Enter
1CVE timeline, what the three beats areBuild vulnerable stack
2Container roles, seeded admin passwordGenerate payloads
3What's inside each tarballBeat 1 — baseline
4Why /admin is 401, what normal extraction looks likeBeat 2 — exploit
5The exact traversal math, what gets overwrittenSwap to fixed stack
6What filter='data' does and why it worksBeat 3 — verify
7Key takeaways + broader ZipSlip patternTeardown

Running beats individually

If you want to step through manually:

# Vulnerable stack
docker compose -f docker-compose.vulnerable.yml up --build -d
docker compose -f docker-compose.vulnerable.yml exec attacker python craft_malicious.py
docker compose -f docker-compose.vulnerable.yml exec attacker python demo.py baseline
docker compose -f docker-compose.vulnerable.yml exec attacker python demo.py exploit

# Fixed stack
docker compose -f docker-compose.vulnerable.yml down
docker compose -f docker-compose.fixed.yml up --build -d
docker compose -f docker-compose.fixed.yml exec attacker python craft_malicious.py
docker compose -f docker-compose.fixed.yml exec attacker python demo.py verify

# Teardown
docker compose -f docker-compose.fixed.yml down

Visual inspection

Download Tool