{"record":{"id":"ccea72bdc0aa34fa","repo":"BookStackApp/BookStack","slug":"bad-file-path-found-in-module-zip-file-name","errorCode":null,"errorMessage":"Bad file path found in module ZIP file: {$name}","messagePattern":"Bad file path found in module ZIP file: (.+?)","errorType":"exception","errorClass":"ThemeModuleException","httpStatus":null,"severity":"error","filePath":"app/Theming/ThemeModuleZip.php","lineNumber":40,"sourceCode":"            $name = $zip->getNameIndex($i);\n            $entryIsDir = str_ends_with($name, \"/\");\n            if ($entryIsDir) {\n                continue;\n            }\n\n            $stream = $zip->getStreamIndex($i);\n\n            if ($prefix) {\n                if (!str_starts_with($name, $prefix) || $name === $prefix) {\n                    continue;\n                }\n                $name = str_replace($prefix, '', $name);\n            }\n\n            try {\n                $targetPath = $destinationPath . DIRECTORY_SEPARATOR . FilePathNormalizer::normalize($name);\n            } catch (\\Exception $exception) {\n                throw new ThemeModuleException(\"Bad file path found in module ZIP file: {$name}\");\n            }\n\n            $targetPathDir = dirname($targetPath);\n            if (!is_dir($targetPathDir)) {\n                $dirCreated = mkdir($targetPathDir, 0777, true);\n                if (!$dirCreated) {\n                    throw new ThemeModuleException(\"Failed to create directory {$targetPathDir} when extracting module files\");\n                }\n            }\n\n            $targetFile = fopen($targetPath, 'w');\n            $written = stream_copy_to_stream($stream, $targetFile);\n            if (!$written) {\n                throw new ThemeModuleException(\"Failed to write to {$targetPath} when extracting module files\");\n            }\n            fclose($targetFile);\n        }\n","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Theming/ThemeModuleZip.php#L22-L58","documentation":"ThemeModuleException thrown in ThemeModuleZip::extractTo when a ZIP entry's name yields an unsafe target path — FilePathNormalizer::normalize rejects paths attempting traversal (e.g. '../') outside the destination. Input at fault: a malicious or malformed entry name inside the module ZIP.","triggerScenarios":"Thrown at app/Theming/ThemeModuleZip.php:40 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Reject/re-upload a module ZIP that contains path-traversal entries","Obtain the module ZIP from a trusted source","Inspect the ZIP's entry names for '../' or absolute paths before installing"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}