alibaba/canal · error · IllegalArgumentException

Invalid destination path

Error message

Invalid destination path

What it means

Thrown by FileUtils.validateFileName() as a path-traversal guard. It resolves both baseDir and the combined baseDir+destination to their canonical (absolute, symlink-resolved) paths, then checks that the full path starts with basePath + File.separator. If the destination contains `../` sequences or symlinks that escape the base directory, the check fails and this exception is thrown.

Source

Thrown at common/src/main/java/com/alibaba/otter/canal/common/utils/FileUtils.java:107

        return res.toString();
    }

    /**
     * 校验自定义的文件名,是否在允许的基目录范围内,如何合法就返回全路径,否则就直接报错
     *
     * @param baseDir
     * @param destination
     * @return
     */
    public static String validateFileName(String baseDir, String destination) {
        try {
            // 验证 destination 是否在允许的基目录范围内
            String basePath = new File(baseDir).getCanonicalPath();
            String fullPath = new File(basePath, destination).getCanonicalPath();

            // 检查 fullPath 是否以 basePath 开头
            if (!fullPath.startsWith(basePath + File.separator)) {
                throw new IllegalArgumentException("Invalid destination path");
            }

            return fullPath;
        } catch (IOException e) {
            throw new RuntimeException("Failed to read file", e);
        }
    }

    public static void main(String[] args) throws IOException {
        String fullPath = validateFileName("/tmp/", "1.txt");
        System.out.println(fullPath);
        System.out.println(org.apache.commons.io.FileUtils.readLines(new File(fullPath)));

        fullPath = validateFileName("/tmp/", "test");
        fullPath = validateFileName(fullPath,"1.txt");
        System.out.println(fullPath);
        System.out.println(org.apache.commons.io.FileUtils.readLines(new File(fullPath)));

View on GitHub (pinned to 87be50e876)

Solutions

  1. Ensure the destination parameter contains no `../` sequences or absolute path prefixes.
  2. Verify that no symlinks within the base directory tree resolve to locations outside baseDir.
  3. Pass an absolute, canonical baseDir to avoid ambiguity in path resolution.
  4. Sanitize user/config-provided path components by rejecting any input containing `..` or starting with `/`.

Example fix

// before — user input used directly as destination
String dest = request.getParam("name"); // could be "../../etc/passwd"
String path = FileUtils.validateFileName(baseDir, dest);

// after — sanitize input
String dest = request.getParam("name");
if (dest.contains("..") || dest.startsWith("/")) {
    throw new IllegalArgumentException("Invalid name");
}
String path = FileUtils.validateFileName(baseDir, dest);
Defensive patterns

Strategy: validation

Validate before calling

// Sanitize destination before calling validateFileName
if (destination == null || destination.contains("..") || destination.startsWith("/")
    || destination.contains(File.separator + "..")) {
    throw new IllegalArgumentException("Invalid destination: path traversal detected");
}
String safePath = FileUtils.validateFileName(baseDir, destination);

Type guard

null

Try / catch

try {
    String path = FileUtils.validateFileName(baseDir, destination);
} catch (IllegalArgumentException e) {
    if ("Invalid destination path".equals(e.getMessage())) {
        logger.warn("Rejected path traversal attempt: baseDir={}, dest={}", baseDir, destination);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling validateFileName(baseDir, destination) where destination resolves outside baseDir — e.g. destination contains `../` that escapes, or a symlink within the path points outside baseDir, or destination is an absolute path pointing elsewhere.

Common situations: User-supplied or config-supplied file paths are used without sanitization; canal destination or instance name contains traversal characters; a symlink in the data directory resolves outside the allowed base; the baseDir itself is relative and resolves unexpectedly.

Related errors


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/e93618f671d4d140. Report an issue: GitHub.