{"record":{"id":"a623b32aa75a0d7a","repo":"jeecgboot/JeecgBoot","slug":"zip-bomb-a623b3","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":441,"sourceCode":"                    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\n                        long bytesCopied = copyLimited(is, os, MAX_FILE_SIZE);\n                        totalUnzippedSize += bytesCopied;\n\n                        if (totalUnzippedSize > MAX_TOTAL_SIZE) {\n                            throw new IOException(\"解压总大小超限，可能是zip bomb攻击\");\n                        }\n                    }\n\n                    // 解压完成后回调\n                    if (afterExtract != null) {\n                        afterExtract.accept(newPath.toFile());\n                    }\n                }\n            }\n        }\n    }\n\n    //update-begin---author:scott ---date:2026-04-16  for：【issues/9551】macOS压缩包隐藏文件过滤-----------\n    /**\n     * 过滤压缩包中的系统隐藏文件，例如 macOS 自动生成的 __MACOSX 和 ._ 文件。\n     */\n    static boolean shouldSkipZipEntry(String entryName) {\n        if (oConvertUtils.isEmpty(entryName)) {","sourceCodeStart":423,"sourceCodeEnd":459,"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#L423-L459","documentation":"Thrown by AiragKnowledgeDocServiceImpl.unzipFile() when the cumulative uncompressed size of all extracted files exceeds MAX_TOTAL_SIZE (1 GB / 1073741824 bytes). This is a zip-bomb defense against decompression ratio attacks where a small archive expands to enormous size.","triggerScenarios":"Extracting a zip archive whose total uncompressed content exceeds 1 GB. The check runs after each file's bytes are copied, so it triggers mid-extraction when the running total crosses the threshold.","commonSituations":"A zip-bomb with high compression ratio (e.g. 42.zip); a legitimately large archive containing large media files or datasets; many moderate-sized files that together exceed 1 GB.","solutions":["Reduce the total size of files in the archive to under 1 GB uncompressed.","Split large archives into smaller batches and import separately.","If legitimate archives consistently exceed 1 GB, increase MAX_TOTAL_SIZE after assessing available disk space."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    unzipFile(zipFilePath, targetDir, callback);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"解压总大小超限\")) {\n        log.warn(\"Zip total size limit exceeded: {}\", e.getMessage());\n        throw new JeecgBootException(\"压缩包总大小超过1GB限制，请减少文件大小或分批上传\");\n    }\n    throw e;\n}","preventionTips":["Keep total uncompressed size under 1 GB per archive.","Remove large media files or compress them further before archiving.","Split large archives into multiple smaller zip files for separate import."],"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"}