jeecgboot/JeecgBoot · critical · JeecgBootException

文件路径包含非法字符

Error message

文件路径包含非法字符

What it means

Thrown by SsrfFileTypeFilter.checkPathTraversal when the supplied filePath contains '..'. This is the general (download/serve) path-traversal guard, applied to file read/serve endpoints. It runs after a blank check and precedes the URL-encoded-variant check. Blank paths are allowed through (early return).

Source

Thrown at jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/SsrfFileTypeFilter.java:303

        }

        // 3. 限制字符集(只允许字母、数字、下划线、横线、斜杠)
        if (!normalized.matches("^[a-zA-Z0-9/_-]+$")) {
            throw new JeecgBootException("上传业务路径包含非法字符!");
        }
    }

    /**
     * 校验文件路径安全性,防止路径遍历攻击
     * @param filePath 文件路径
     */
    public static void checkPathTraversal(String filePath) {
        if (StringUtils.isBlank(filePath)) {
            return;
        }
        // 1. 防止路径遍历:不允许 ..
        if (filePath.contains("..")) {
            throw new JeecgBootException("文件路径包含非法字符");
        }
        // 2. 防止URL编码绕过:%2e = .
        String fileLower = filePath.toLowerCase();
        if (fileLower.contains("%2e")) {
            throw new JeecgBootException("文件路径包含非法字符");
        }
    }

    //update-begin---author:zhangdaihao ---date:2026-04-15  for:【issues/9553】修复二次SSRF漏洞,对HTTP下载URL进行安全校验-----------
    /**
     * 校验HTTP(S) URL,防止SSRF攻击(最小化拦截,只挡真正危险的目标)。
     * 规则:
     * 1. 仅允许 http / https 协议;
     * 2. 解析主机IP,拒绝 loopback(127.x / ::1)和 link-local(169.254.x,含云元数据 169.254.169.254 / fe80:);
     * 注意:RFC1918 私网段(10/172.16/192.168)允许通过,兼容企业内网 MinIO/OSS/文件服务等合法用途。
     *
     * @param fileUrl HTTP(S) URL
     */

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Do not send '..' in file paths; resolve to absolute canonical paths server-side and verify the result is under the allowed root.
  2. Validate the file id/name against a whitelist or database record rather than accepting a raw path.
  3. Use Path.normalize() + startsWith(allowedRoot) server-side as defense-in-depth.
  4. Strip '..' on the client and reject paths that still contain it.

Example fix

// before
String filePath = "../../secret.txt";
checkPathTraversal(filePath); // throws

// after
String filePath = "reports/2026/q1.pdf";
checkPathTraversal(filePath);
Defensive patterns

Strategy: validation

Validate before calling

if (filePath != null && filePath.contains("..")) throw new IllegalArgumentException("traversal");

Type guard

public static boolean pathNoDotDot(String p){ return p == null || !p.contains(".."); }

Try / catch

try { SsrfFileTypeFilter.checkPathTraversal(filePath); }
catch (JeecgBootException e) { response.sendError(400, e.getMessage()); }

Prevention

When it happens

Trigger: A file read/serve/download request with a path like '../../etc/passwd', '/static/../../../config', or any path containing '..'. Common in URL-based file viewers and attachment downloaders.

Common situations: Filename field concatenated into a server path; an attacker manipulating a 'file=' query param; a relative path that legitimately needs '..' (which must be rewritten to an absolute canonical path instead).

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/8931ff878da040bc. Report an issue: GitHub.