{"record":{"id":"8d2184c4c31426c8","repo":"apache/seatunnel","slug":"bad-zip-entry","errorCode":null,"errorMessage":"Bad zip entry","messagePattern":"Bad zip entry","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"seatunnel-core/seatunnel-core-starter/src/main/java/org/apache/seatunnel/core/starter/utils/CompressionUtils.java","lineNumber":117,"sourceCode":"     * @throws FileNotFoundException file not found exception\n     * @throws ArchiveException archive exception\n     */\n    public static void unTar(final File inputFile, final File outputDir)\n            throws IOException, ArchiveException {\n\n        log.info(\n                \"Untaring {} to dir {}.\", inputFile.getAbsolutePath(), outputDir.getAbsolutePath());\n\n        final List<File> untaredFiles = new LinkedList<>();\n        try (final InputStream is = new FileInputStream(inputFile);\n                final TarArchiveInputStream debInputStream =\n                        (TarArchiveInputStream)\n                                new ArchiveStreamFactory().createArchiveInputStream(\"tar\", is)) {\n            TarArchiveEntry entry = null;\n            while ((entry = (TarArchiveEntry) debInputStream.getNextEntry()) != null) {\n                final File outputFile = new File(outputDir, entry.getName());\n                if (!outputFile.toPath().normalize().startsWith(outputDir.toPath())) {\n                    throw new IllegalStateException(\"Bad zip entry\");\n                }\n                if (entry.isDirectory()) {\n                    log.info(\n                            \"Attempting to write output directory {}.\",\n                            outputFile.getAbsolutePath());\n                    if (!outputFile.exists()) {\n                        log.info(\n                                \"Attempting to create output directory {}.\",\n                                outputFile.getAbsolutePath());\n                        if (!outputFile.mkdirs()) {\n                            throw new IllegalStateException(\n                                    String.format(\n                                            \"Couldn't create directory %s.\",\n                                            outputFile.getAbsolutePath()));\n                        }\n                    }\n                } else {\n                    log.info(\"Creating output file {}.\", outputFile.getAbsolutePath());","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-core/seatunnel-core-starter/src/main/java/org/apache/seatunnel/core/starter/utils/CompressionUtils.java#L99-L135","documentation":"unTar extracts a tar archive and rejects entries whose normalized path escapes the output directory. This throws IllegalStateException('Bad zip entry') as a Zip Slip / path traversal guard, preventing malicious archives from writing files outside outputDir.","triggerScenarios":"Extracting a tar file containing entries like '../../etc/passwd' or absolute/symlink-resolving names whose normalized path is not under outputDir.","commonSituations":"Processing untrusted plugin packages, archives crafted by attackers (CVE-style Zip Slip), or archives built on Windows with path components that normalize oddly.","solutions":["Inspect the archive with `tar -tf file.tar` and remove/reject entries containing '..' or absolute paths","Obtain the archive from a trusted source and repackage it","Wrap extraction in try-catch on IllegalStateException and fail the deployment cleanly"],"exampleFix":"// before\nCompressionUtils.unTar(new File(\"plugin.tar\"), pluginDir);\n// after\nif (TarChecker.containsTraversal(new File(\"plugin.tar\"))) {\n    throw new IllegalArgumentException(\"Archive has unsafe paths\");\n}\nCompressionUtils.unTar(new File(\"plugin.tar\"), pluginDir);","handlingStrategy":"try-catch","validationCode":"// pre-scan archive entry names\nboolean safe = entries.stream().allMatch(n -> !n.contains(\"..\") && !Paths.get(n).isAbsolute());","typeGuard":null,"tryCatchPattern":"try { CompressionUtils.unTar(archive, dir); } catch (IllegalStateException e) { log.error(\"Unsafe archive: {}\", e.getMessage()); throw new SecurityException(e); }","preventionTips":["Only extract archives from trusted sources","Pre-scan entry names for '..' and absolute paths","Extract into a fresh, dedicated directory"],"tags":["tar","security","path-traversal"],"backgroundTag":"path-traversal-blocked","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}