@@ -425,12 +425,41 @@ void ImportEPUB::ExtractContainer()
425425 // If there is no file name then we can't do anything with it.
426426 if (!qfile_name.isEmpty ()) {
427427
428- // for security reasons we need the file path to always be inside the
429- // target folder and not outside, so we will remove all relative upward
430- // paths segments ".." from the file path before prepending the target
431- // folder to create the final target path
432- qfile_name = qfile_name.replace (" ../" ," " );
433- cp437_file_name = cp437_file_name.replace (" ../" ," " );
428+ // for security reasons against maliciously crafted zip archives
429+ // we need the file path to always be inside the target folder
430+ // and not outside, so we will remove all illegal backslashes
431+ // and all relative upward paths segments "/../" from the zip's local
432+ // file name/path before prepending the target folder to create
433+ // the final path
434+
435+ QString original_path = qfile_name;
436+ bool evil_or_corrupt_epub = false ;
437+
438+ if (qfile_name.contains (" \\ " )) evil_or_corrupt_epub = true ;
439+ qfile_name = " /" + qfile_name.replace (" \\ " ," " );
440+
441+ if (qfile_name.contains (" /../" )) evil_or_corrupt_epub = true ;
442+ qfile_name = qfile_name.replace (" /../" ," /" );
443+
444+ while (qfile_name.startsWith (" /" )) {
445+ qfile_name = qfile_name.remove (0 ,1 );
446+ }
447+
448+ if (cp437_file_name.contains (" \\ " )) evil_or_corrupt_epub = true ;
449+ cp437_file_name = " /" + cp437_file_name.replace (" \\ " ," " );
450+
451+ if (cp437_file_name.contains (" /../" )) evil_or_corrupt_epub = true ;
452+ cp437_file_name = cp437_file_name.replace (" /../" ," /" );
453+
454+ while (cp437_file_name.startsWith (" /" )) {
455+ cp437_file_name = cp437_file_name.remove (0 ,1 );
456+ }
457+
458+ if (evil_or_corrupt_epub) {
459+ unzCloseCurrentFile (zfile);
460+ unzClose (zfile);
461+ throw (EPUBLoadParseError (QString (QObject::tr (" Possible evil or corrupt epub file name: %1" )).arg (original_path).toStdString ()));
462+ }
434463
435464 // We use the dir object to create the path in the temporary directory.
436465 // Unfortunately, we need a dir ojbect to do this as it's not a static function.
0 commit comments