Projects
Eulaceura:Mainline:GA
sigil
_service:obs_scm:harden-plugin-unzipping-to-zip...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:harden-plugin-unzipping-to-zip-slip-attacks.patch of Package sigil
From 0979ba8d10c96ebca330715bfd4494ea0e019a8f Mon Sep 17 00:00:00 2001 From: Kevin Hendricks <kevin.b.hendricks@icloud.com> Date: Fri, 12 Jul 2019 14:08:44 -0400 Subject: [PATCH 1/1] harden plugin unzipping to zip-slip attacks --- src/Misc/Utility.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/sigil_exception.h | 10 ++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/Misc/Utility.cpp b/src/Misc/Utility.cpp index 81100a75c..853c4035f 100644 --- a/src/Misc/Utility.cpp +++ b/src/Misc/Utility.cpp @@ -1,5 +1,6 @@ /************************************************************************ ** +** Copyright (C) 2019 Kevin B. Hendricks, Stratford, Ontario Canada ** Copyright (C) 2009, 2010, 2011 Strahinja Markovic <strahinja.markovic@gmail.com> ** ** This file is part of Sigil. @@ -715,6 +716,44 @@ bool Utility::UnZip(const QString &zippath, const QString &destpath) // If there is no file name then we can't do anything with it. if (!qfile_name.isEmpty()) { + + // for security reasons against maliciously crafted zip archives + // we need the file path to always be inside the target folder + // and not outside, so we will remove all illegal backslashes + // and all relative upward paths segments "/../" from the zip's local + // file name/path before prepending the target folder to create + // the final path + + QString original_path = qfile_name; + bool evil_or_corrupt_epub = false; + + if (qfile_name.contains("\\")) evil_or_corrupt_epub = true; + qfile_name = "/" + qfile_name.replace("\\",""); + + if (qfile_name.contains("/../")) evil_or_corrupt_epub = true; + qfile_name = qfile_name.replace("/../","/"); + + while(qfile_name.startsWith("/")) { + qfile_name = qfile_name.remove(0,1); + } + + if (cp437_file_name.contains("\\")) evil_or_corrupt_epub = true; + cp437_file_name = "/" + cp437_file_name.replace("\\",""); + + if (cp437_file_name.contains("/../")) evil_or_corrupt_epub = true; + cp437_file_name = cp437_file_name.replace("/../","/"); + + while(cp437_file_name.startsWith("/")) { + cp437_file_name = cp437_file_name.remove(0,1); + } + + if (evil_or_corrupt_epub) { + unzCloseCurrentFile(zfile); + unzClose(zfile); + // throw (UNZIPLoadParseError(QString(QObject::tr("Possible evil or corrupt zip file name: %1")).arg(original_path).toStdString())); + return false; + } + // We use the dir object to create the path in the temporary directory. // Unfortunately, we need a dir ojbect to do this as it's not a static function. // Full file path in the temporary directory. diff --git a/src/sigil_exception.h b/src/sigil_exception.h index a6561d5c2..dcc0e0fca 100644 --- a/src/sigil_exception.h +++ b/src/sigil_exception.h @@ -1,5 +1,6 @@ /************************************************************************ ** +** Copyright (C) 2019 Kevin B. Hendricks, Stratford, Ontario Canada ** Copyright (C) 2015 John Schember <john@nachtimwald.com> ** Copyright (C) 2009, 2010, 2011 Strahinja Markovic <strahinja.markovic@gmail.com> ** @@ -132,4 +133,13 @@ public: EPUBLoadParseError(const std::string &msg) : std::runtime_error(msg) { }; }; + +/** + * Thrown for Invalid EPUB errors while loading and parsing content files. + */ +class UNZIPLoadParseError : public std::runtime_error { +public: + UNZIPLoadParseError(const std::string &msg) : std::runtime_error(msg) { }; +}; + #endif // SG_EXCEPTION_H -- 2.20.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2