Skip to content

Project 3: CVE Patch Autopsy


The Problem

Security advisories often say what a vulnerability is, but they do not always explain clearly why the bug existed or why the patch fixed it. I wanted to show that I could read a real vulnerability, understand the root cause, and explain it without just repeating the CVE summary.

Repository

View the GitHub repository

What Was Built/Done

I produced a focused technical write-up and small proof-of-concept lab around a real path traversal vulnerability pattern, using Apache HTTP Server CVE-2021-41773 as the reference case.

I did not attack any real server. I studied the public advisory and patch behavior, then built a small Python application that reproduced the same class of mistake: unsafe path normalization before serving local files.

The project had three parts:

  1. A short CVE autopsy report explaining the vulnerability in plain language.
  2. A minimal vulnerable Python file-serving example.
  3. A fixed version with test cases proving which traversal inputs were blocked.

The repository included tests such as:

Allowed:
GET /files/readme.txt

Blocked:
GET /files/../../etc/passwd
GET /files/.%2e/.%2e/etc/passwd
GET /files/subdir/../../../secret.txt

The output was not a weaponized exploit. It was a controlled explanation of the bug class, the failed assumption, and the defensive fix.

Why It's Not Trivial

The core challenge was understanding that path traversal is not only about spotting ../ in a string.

The important decision I had to make was how to validate paths safely:

Weak approach:
Reject requests that contain "../" as a substring.

Better approach:
Decode input, normalize the path, resolve it to an absolute path, and verify that the final path still stays inside the intended base directory.

I also had to think through encoding. A simple filter might catch ../, but miss encoded or partially normalized variants. That made the project more interesting than writing a basic vulnerable endpoint.

The most useful part was writing tests that proved both the vulnerable behavior and the fixed behavior. The tests forced me to be precise about what the application allowed and blocked.

Skills Demonstrated

  • Reading and interpreting a real CVE and public vulnerability write-up
  • Path traversal root-cause analysis
  • Python secure file path handling
  • URL decoding and path normalization analysis
  • Writing regression tests for security fixes
  • Explaining vulnerability mechanics without overstating impact

The Deliverable

I created a GitHub repository with:

cve-patch-autopsy-path-traversal/
├── report/
│   └── cve-autopsy.md
├── vulnerable_app/
│   └── app.py
├── fixed_app/
│   └── app.py
├── tests/
│   └── test_path_traversal.py
├── screenshots/
├── README.md
└── lessons-learned.md

The main portfolio deliverable was the cve-autopsy.md report. I made the write-up lead with a short before/after explanation so a reviewer could quickly see that I understood the vulnerability mechanism.

The portfolio page showed:

  • The vulnerable code snippet
  • The fixed code snippet
  • The test cases
  • A table of allowed vs blocked paths
  • A short explanation of why blacklist filtering failed
  • A section explaining what I intentionally did not test

Write-Up Angle

I framed the write-up around this idea:

“I did not want to just say ‘path traversal bad.’ I wanted to understand exactly where the trust boundary failed.”

The narrative walks through how I approached the vulnerability:

  • I started from the public CVE description.
  • I identified the underlying bug class: unsafe path handling.
  • I recreated the mistake in a small local Python app.
  • I tested simple traversal first.
  • I added encoded traversal cases.
  • I fixed the logic by validating the resolved final path.
  • I wrote tests to prove the fix worked.

I also gave lessons-learned.md its own section because that was where the project became more than a code example. In that file, I documented what I initially assumed — that blocking ../ would be enough — and what I learned after testing encoded paths, normalization behavior, and final path resolution. That section showed how my understanding changed during the project.

The strongest section of the write-up explains what changed after my first failed fix:

My first fix blocked literal "../" strings. That looked effective until I tested encoded traversal input. I changed the defense so the application decoded and resolved the requested path, then checked whether the final absolute path stayed inside the intended directory.

That made the project read like a small vulnerability research exercise, not a generic “I read about a CVE” summary.

Honest Scope

This project did not reproduce or exploit the full Apache HTTP Server vulnerability. I used CVE-2021-41773 as a real-world reference point, then recreated the same class of path validation mistake in a small local program that I controlled.

Limitations:

- It focused on path traversal mechanics, not complete web server internals.
- It did not cover every possible encoding or filesystem edge case.
- It did not replace professional code review or fuzzing.
- It was a focused vulnerability autopsy and secure-coding demonstration.