From 220a581ff8dd2045b4355f380898fbc34855d5d7 Mon Sep 17 00:00:00 2001 From: Kevin Hendricks <kevin.b.hendricks@icloud.com> Date: Thu, 27 Jun 2019 12:00:31 -0400 Subject: [PATCH] harden further by throwing exception --- src/zipios/src/zipextraction.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/zipios/src/zipextraction.cpp b/src/zipios/src/zipextraction.cpp index 5783b79..f8c6e12 100644 --- a/src/zipios/src/zipextraction.cpp +++ b/src/zipios/src/zipextraction.cpp @@ -88,13 +88,19 @@ void ExtractZipToFolder( const fs::path &path_to_zip, const fs::path &path_to_fo size_t n = azipfilepath.length(); // stripping out any backslashes during copy + bool evil_or_corrupt_epub = false; string securefilepath = "/"; securefilepath.reserve(n+1); for (size_t i=0; i < n; i++) { - if (azipfilepath[i] != '\\') securefilepath.append(1, azipfilepath[i]); + if (azipfilepath[i] != '\\') { + securefilepath.append(1, azipfilepath[i]); + } else { + evil_or_corrupt_epub = true; + } } // now replace all upward path segments "/../" with "/" size_t index = securefilepath.find("/../", 0); + if (index != std::string::npos) evil_or_corrupt_epub = true; while(index != std::string::npos) { securefilepath.replace(index, 4,"/"); index = securefilepath.find("/../", index); @@ -102,6 +108,10 @@ void ExtractZipToFolder( const fs::path &path_to_zip, const fs::path &path_to_fo // finally remove any leading "/" securefilepath.erase(0,securefilepath.find_first_not_of("/")); + if (evil_or_corrupt_epub) { + throw InvalidStateException( "evil or corrupt epub detected with local file path: " + azipfilepath ) ; + } + fs::path new_file_path = path_to_folder / securefilepath; CreateFilepath( new_file_path );