apache/seatunnel · error · IllegalStateException

Bad zip entry

Error message

Bad zip entry

What it means

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.

Source

Thrown at seatunnel-core/seatunnel-core-starter/src/main/java/org/apache/seatunnel/core/starter/utils/CompressionUtils.java:117

     * @throws FileNotFoundException file not found exception
     * @throws ArchiveException archive exception
     */
    public static void unTar(final File inputFile, final File outputDir)
            throws IOException, ArchiveException {

        log.info(
                "Untaring {} to dir {}.", inputFile.getAbsolutePath(), outputDir.getAbsolutePath());

        final List<File> untaredFiles = new LinkedList<>();
        try (final InputStream is = new FileInputStream(inputFile);
                final TarArchiveInputStream debInputStream =
                        (TarArchiveInputStream)
                                new ArchiveStreamFactory().createArchiveInputStream("tar", is)) {
            TarArchiveEntry entry = null;
            while ((entry = (TarArchiveEntry) debInputStream.getNextEntry()) != null) {
                final File outputFile = new File(outputDir, entry.getName());
                if (!outputFile.toPath().normalize().startsWith(outputDir.toPath())) {
                    throw new IllegalStateException("Bad zip entry");
                }
                if (entry.isDirectory()) {
                    log.info(
                            "Attempting to write output directory {}.",
                            outputFile.getAbsolutePath());
                    if (!outputFile.exists()) {
                        log.info(
                                "Attempting to create output directory {}.",
                                outputFile.getAbsolutePath());
                        if (!outputFile.mkdirs()) {
                            throw new IllegalStateException(
                                    String.format(
                                            "Couldn't create directory %s.",
                                            outputFile.getAbsolutePath()));
                        }
                    }
                } else {
                    log.info("Creating output file {}.", outputFile.getAbsolutePath());

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Inspect the archive with `tar -tf file.tar` and remove/reject entries containing '..' or absolute paths
  2. Obtain the archive from a trusted source and repackage it
  3. Wrap extraction in try-catch on IllegalStateException and fail the deployment cleanly

Example fix

// before
CompressionUtils.unTar(new File("plugin.tar"), pluginDir);
// after
if (TarChecker.containsTraversal(new File("plugin.tar"))) {
    throw new IllegalArgumentException("Archive has unsafe paths");
}
CompressionUtils.unTar(new File("plugin.tar"), pluginDir);
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-scan archive entry names
boolean safe = entries.stream().allMatch(n -> !n.contains("..") && !Paths.get(n).isAbsolute());

Try / catch

try { CompressionUtils.unTar(archive, dir); } catch (IllegalStateException e) { log.error("Unsafe archive: {}", e.getMessage()); throw new SecurityException(e); }

Prevention

When it happens

Trigger: Extracting a tar file containing entries like '../../etc/passwd' or absolute/symlink-resolving names whose normalized path is not under outputDir.

Common situations: Processing untrusted plugin packages, archives crafted by attackers (CVE-style Zip Slip), or archives built on Windows with path components that normalize oddly.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/8d2184c4c31426c8. Report an issue: GitHub.