From a6121c7f676e112145a0c97631da9ab4c6239f42 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 8 Jul 2024 22:13:04 +0200 Subject: [PATCH] Fix path traversal in mainmenu's extract_zip --- src/filesys.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/filesys.cpp b/src/filesys.cpp index 26cdaba07..733a3b203 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -954,13 +954,22 @@ bool extractZipFile(io::IFileSystem *fs, const char *filename, const std::string const io::IFileList* files_in_zip = opened_zip->getFileList(); for (u32 i = 0; i < files_in_zip->getFileCount(); i++) { - std::string fullpath = destination + DIR_DELIM; - fullpath += files_in_zip->getFullFileName(i).c_str(); - std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath); - if (files_in_zip->isDirectory(i)) continue; // ignore, we create dirs as necessary + const auto &filename = files_in_zip->getFullFileName(i); + std::string fullpath = destination + DIR_DELIM; + fullpath += filename.c_str(); + + fullpath = fs::RemoveRelativePathComponents(fullpath); + if (!fs::PathStartsWith(fullpath, destination)) { + warningstream << "fs::extractZipFile(): refusing to extract file \"" + << filename.c_str() << "\"" << std::endl; + continue; + } + + std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath); + if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) return false;