{"record":{"id":"6e7d22d87bffa568","repo":"jeecgboot/JeecgBoot","slug":"zip-bomb","errorCode":null,"errorMessage":"解压文件数量超限，可能是zip bomb攻击","messagePattern":"解压文件数量超限，可能是zip bomb攻击","errorType":"validation","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/llm/service/impl/AiragKnowledgeDocServiceImpl.java","lineNumber":418,"sourceCode":"     * @author chenrui\n     * @date 2025/4/28 17:02\n     */\n    private static void unzipFile(Path zipFilePath, Path targetDir, Consumer<File> afterExtract) throws IOException {\n        long totalUnzippedSize = 0;\n        int entryCount = 0;\n\n        if (!Files.exists(targetDir)) {\n            Files.createDirectories(targetDir);\n        }\n\n        try (ZipFile zipFile = new ZipFile(zipFilePath.toFile())) {\n            Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();\n\n            while (entries.hasMoreElements()) {\n                ZipArchiveEntry entry = entries.nextElement();\n                entryCount++;\n                if (entryCount > MAX_ENTRY_COUNT) {\n                    throw new IOException(\"解压文件数量超限，可能是zip bomb攻击\");\n                }\n\n                //update-begin---author:scott ---date:2026-04-16  for：【issues/9551】macOS压缩包隐藏文件过滤-----------\n                if (shouldSkipZipEntry(entry.getName())) {\n                    log.info(\"跳过压缩包中的隐藏文件: {}\", entry.getName());\n                    continue;\n                }\n                //update-end---author:scott ---date:2026-04-16  for：【issues/9551】macOS压缩包隐藏文件过滤-----------\n\n                Path newPath = safeResolve(targetDir, entry.getName());\n\n                if (entry.isDirectory()) {\n                    Files.createDirectories(newPath);\n                } else {\n                    Files.createDirectories(newPath.getParent());\n                    try (InputStream is = zipFile.getInputStream(entry);\n                         OutputStream os = Files.newOutputStream(newPath)) {\n","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/llm/service/impl/AiragKnowledgeDocServiceImpl.java#L400-L436","documentation":"Thrown by AiragKnowledgeDocServiceImpl.unzipFile() when the number of entries in the zip archive exceeds MAX_ENTRY_COUNT (10000). This is a zip-bomb defense — malicious archives can contain millions of entries to exhaust disk space or processing time. The counter increments for every entry including directories and skipped entries.","triggerScenarios":"Uploading a zip archive containing more than 10000 entries. Each ZipArchiveEntry increments the counter before any skip logic runs, so even entries that would be filtered (like macOS hidden files) count toward the limit.","commonSituations":"A legitimate archive with many small files (e.g. node_modules, source code repositories) exceeds 10000 entries; a malicious zip-bomb designed with excessive entries; a large dataset archive.","solutions":["Reduce the number of files in the zip archive by removing unnecessary files or splitting into multiple archives.","If the limit is too low for legitimate use cases, increase MAX_ENTRY_COUNT (currently 10000) — but weigh the security implications.","Exclude hidden files, metadata directories (.git, __MACOSX, node_modules) before zipping."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-check zip entry count before full extraction\ntry (ZipFile zf = new ZipFile(zipFile.toFile())) {\n    int count = 0;\n    Enumeration<ZipArchiveEntry> e = zf.getEntries();\n    while (e.hasMoreElements()) { e.nextElement(); count++; }\n    if (count > 10000) {\n        throw new JeecgBootException(\"压缩包内文件数量超过10000个，请精简后重试\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    unzipFile(zipFilePath, targetDir, callback);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"zip bomb\")) {\n        log.warn(\"Zip bomb entry count detected: {}\", e.getMessage());\n        throw new JeecgBootException(\"压缩包文件数量超限，请减少文件数量\");\n    }\n    throw e;\n}","preventionTips":["Exclude unnecessary files (node_modules, .git, __MACOSX) before creating the archive.","Split large archives into smaller batches.","Inform users of the 10000-entry limit in upload documentation."],"tags":["security","zip-bomb","zip","dos-prevention","rag"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}