notes 2026-09-20 · 3 min read · updated 2026-09-20

File Uploads, Path Traversal and Archive Extraction

Canonicalization and encoding, LFI wrappers, image parser bugs and Zip Slip: the path the server actually opens versus the one you thought you sent.

File Uploads, Path Traversal and Archive Extraction

Every item here ends at the same question. After all the normalising, decoding and extracting, which path does the server open, and who chose it.

File Uploads

An unsafe upload does not begin with a blocked extension. It begins when the server trusts the file too much after receiving it. Uploads pass through filename, MIME type, extension, storage, parsers, preview generation, antivirus and later delivery. Each stage adds a different boundary. Impact may be web shell execution, stored XSS, parser SSRF, overwrite, Zip Slip or an image-library vulnerability. I determine where the file is stored, how it is served and which component processes it before changing extensions or content. Renaming to a UUID outside the web root removes several classes. Magic-byte validation helps, but safe parsers and sandboxing still matter.

1
curl -F 'file=@avatar.svg;type=image/svg+xml' https://app.example.test/upload

Path Traversal

../ is only the most obvious representation of a larger problem: user input influences the final filesystem path. Traversal appears when an application concatenates user-controlled path data to a base directory without safe canonicalization. Encoding, absolute paths, mixed separators and double decoding appear when filters and filesystems interpret the string differently. I identify the expected root, test known lab files and observe normalization before touching sensitive content. String prefix checks can fail with symlinks or canonical paths. Validation needs to happen on the resolved destination.

1
2
GET /download?file=../../../../etc/hostname HTTP/1.1
Host: app.example.test

LFI

LFI proves that the server reads or includes a local file. The distance to RCE depends entirely on how that runtime processes the content. Local File Inclusion appears when controlled path data reaches include or file-read functions. In PHP, include may interpret content as code. Wrappers, logs, session files, temporary uploads and procfs can expand impact in environment-specific ways. I separate file read from code include, identify the language and function involved and test harmless files first. Reading /etc/passwd does not prove RCE. Log poisoning also depends on path, permissions, format and include semantics.

1
2
GET /index.php?page=../../../../etc/hostname HTTP/1.1
Host: app.example.test

Image Processing Pipelines

An image is more than pixels. It is a container of metadata and structures processed by complex native parsers and language bindings. ImageMagick, libvips, Ghostscript and codecs process different formats and delegates. Conversion may invoke supporting components. SVG is also XML and may contain links, scripts or external references depending on the renderer. I identify the actual pipeline, versions and accepted formats before fuzzing. A valid JPEG with canary metadata helps map processing. Strong defense combines format allowlists, re-encoding, sandboxing, resource limits and parser patching.

1
identify -verbose sample.png | head -60

Archive Extraction and Zip Slip

A ZIP file can be stored in a safe directory and still overwrite files outside it when the extractor trusts the internal entry name. Zip Slip uses entries such as ../../target or absolute paths to escape the extraction directory. TAR and other archive formats have equivalent issues. Symlinks inside archives may also redirect writes outside the expected root. I build a lab archive with a canary file and inspect the final extraction path without overwriting sensitive configuration. Comparing canonical destination against canonical root before writing closes traversal. Extractors also need safe symlink and permission handling.

1
zipinfo -1 upload.zip

References

This post is licensed under CC BY 4.0 by the author.