flawopen.com/Path Traversal/Zip Slip
A zip file's internal file list can include entries named things like ../../etc/cron.d/evil. If the code extracting the archive trusts those names blindly, "unzipping a file" can secretly write files anywhere on disk the process has permission to reach — the archive extraction itself is a path traversal vector.
Archive extraction feels like a solved, boring operation — most developers don't think of "unzip this file" as a place untrusted input reaches the filesystem. But every entry name inside a zip (or tar) archive is attacker-controlled if the archive itself came from an untrusted source (a user upload, a downloaded dependency), and naive extraction code that does outputDir + entry.name without validation is exactly the path-traversal pattern, just triggered by archive contents instead of a URL parameter.
for entry in zip_file:
dest = os.path.join(output_dir, entry.name)
write_file(dest, entry.read())
# entry.name could be "../../../etc/cron.d/x"for entry in zip_file:
dest = os.path.realpath(
os.path.join(output_dir, entry.name)
)
if not dest.startswith(
os.path.realpath(output_dir) + os.sep
):
raise ValueError("Unsafe entry path")
write_file(dest, entry.read())Some newer library versions added protections after this pattern was widely publicized in 2018, but many still don't validate by default — check your specific library's documentation rather than assuming, and validate explicitly regardless.