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
- Remove path traversal characters ('..', leading '/', URL-encoded variants) from the logName parameter before calling the endpoint
- URL-encode the logName properly and pass only the plain file name of a log that exists inside the log directory
- If logs legitimately live outside log.path, move/symlink them into the configured log directory or adjust the log.path configuration
- 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
- Never pass user-supplied path input directly as logName
- Allow only plain file names matching a whitelist regex like [\w.-]+
- URL-encode query parameters correctly
- Treat 400 responses on log endpoints as possible traversal attempts and alert
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
- Bad zip entry
- Resolved trace path escapes baseDir: ${traceDir}
- Failed to load AmazonDocumentDB TLS CA bundle:
- KERBEROS_AUTHENTICATION_FAILED
- Server property {} must contain at least one absolute execut
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/efbdea58611a7e50.
Report an issue: GitHub.