apache/seatunnel · warning

Path traversal attempt blocked - Requested: {}, Resolved: {}

Error message

Path traversal attempt blocked - Requested: {}, Resolved: {}, LogDir: {}

What it means

This warning is logged by LogBaseServlet when a REST request for a node log file resolves (after canonicalization) to a path outside the configured log directory. It is a security guard against path traversal attacks like `?logName=../../../etc/passwd`. The servlet returns HTTP 400 and refuses to read the file.

Source

Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/servlet/LogBaseServlet.java:64

     * @param resp response used to return status and log content
     * @param logPath configured log directory
     * @param logName requested log file name from the request URI
     */
    protected void prepareLogResponse(HttpServletResponse resp, String logPath, String logName) {
        if (StringUtils.isBlank(logPath)) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            log.warn(
                    "Log file path is empty, no log file path configured in the current configuration file");
            return;
        }
        String logFilePath = new File(logPath, logName).getPath();
        try {
            String canonicalLogDir = new File(logPath).getCanonicalPath();
            String canonicalFilePath = new File(logFilePath).getCanonicalPath();
            if (!canonicalFilePath.startsWith(canonicalLogDir + File.separator)
                    && !canonicalFilePath.equals(canonicalLogDir)) {
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                log.warn(
                        "Path traversal attempt blocked - Requested: {}, Resolved: {}, LogDir: {}",
                        logName,
                        canonicalFilePath,
                        canonicalLogDir);
                return;
            }
            String logContent = FileUtils.readFileToStr(new File(canonicalFilePath).toPath());
            write(resp, logContent);
        } catch (IOException e) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            log.warn("Failed to resolve log file path: {}, error: {}", logFilePath, e.getMessage());
        } catch (SeaTunnelRuntimeException e) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            log.warn(String.format("Log file content is empty, get log path : %s", logFilePath));
        }
    }
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Remove path traversal characters ('..', leading '/', URL-encoded variants) from the logName parameter before calling the endpoint
  2. URL-encode the logName properly and pass only the plain file name of a log that exists inside the log directory
  3. If logs legitimately live outside log.path, move/symlink them into the configured log directory or adjust the log.path configuration
  4. Check audit logs — if unintended, this may indicate a security scan or attack and the request should be blocked

Example fix

// before
GET /log/../../etc/passwd
// after
GET /log/seatunnel-worker-1.log
Defensive patterns

Strategy: validation

Validate before calling

function isSafeLogName(name) {
  if (!name || name.includes('..') || name.startsWith('/')) {
    throw new Error('Unsafe log name: ' + name);
  }
  return true;
}
isSafeLogName(logName); // call before GET /log/<name>

Type guard

const isPlainFileName = (s) => typeof s === 'string' && /^[\w.\-]+$/.test(s);

Prevention

When it happens

Trigger: Calling the REST log endpoint (e.g. GET /log/<nodeName>) with a logName containing '..' segments, absolute paths, or symlinks that resolve outside the SeaTunnel log directory (log.path config).

Common situations: Automated scripts passing raw user input as logName; misconfigured reverse proxies appending path segments; symlinked log files pointing outside the log dir; probing by security scanners.

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/efbdea58611a7e50. Report an issue: GitHub.