jeecgboot/JeecgBoot · warning · JeecgBootException

非法URL:格式错误

Error message

非法URL:格式错误

What it means

Thrown by checkSsrfHttpUrl when new URI(fileUrl) raises URISyntaxException — the URL string is syntactically invalid per RFC 3986. This guards against malformed URLs that could bypass downstream host/scheme checks or cause unpredictable behavior in URLConnection.

Source

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

    //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
     */
    public static void checkSsrfHttpUrl(String fileUrl) {
        if (StringUtils.isBlank(fileUrl)) {
            throw new JeecgBootException("非法URL:地址为空");
        }
        URI uri;
        try {
            uri = new URI(fileUrl);
        } catch (URISyntaxException e) {
            throw new JeecgBootException("非法URL:格式错误");
        }
        String scheme = uri.getScheme();
        if (scheme == null || !(scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https"))) {
            throw new JeecgBootException("非法URL:仅允许 http / https 协议");
        }
        String host = uri.getHost();
        if (StringUtils.isBlank(host)) {
            throw new JeecgBootException("非法URL:主机名为空");
        }
        // 去掉 IPv6 的中括号
        if (host.startsWith("[") && host.endsWith("]")) {
            host = host.substring(1, host.length() - 1);
        }
        try {
            for (InetAddress addr : InetAddress.getAllByName(host)) {
                if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) {
                    throw new JeecgBootException("非法URL:禁止访问本机或链路本地地址 " + addr.getHostAddress());
                }

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Trim and validate the URL on the client side before submission.
  2. If relative paths are expected, prepend the configured base URL (e.g., MinIO/OSS endpoint) before calling checkSsrfHttpUrl.
  3. URL-encode any user-supplied path segments before constructing the full URL.
  4. Catch JeecgBootException at the controller layer and return a user-friendly Result.error().

Example fix

// before
String fileUrl = userInput; // e.g. "http//broken"
SsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);

// after
String fileUrl = userInput.trim();
if (!fileUrl.startsWith("http://") && !fileUrl.startsWith("https://")) {
    fileUrl = serverBaseUrl + (fileUrl.startsWith("/") ? fileUrl : "/" + fileUrl);
}
SsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);
Defensive patterns

Strategy: validation

Validate before calling

try {
    new URI(fileUrl);
} catch (URISyntaxException e) {
    return Result.error("URL格式不正确: " + fileUrl);
}

Try / catch

try {
    SsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);
} catch (JeecgBootException e) {
    log.warn("Invalid URL format: {}", fileUrl);
    return Result.error(e.getMessage());
}

Prevention

When it happens

Trigger: Passing a URL with illegal characters (e.g., spaces, unencoded brackets), truncated URLs, URLs with mismatched scheme separators (e.g., 'http//example.com'), or strings that look like file paths rather than URLs.

Common situations: User pastes a partial URL missing the '//' after scheme; front-end sends a relative path like '/files/image.png' instead of a full absolute URL; copy-paste introduces invisible/zero-width characters; URL contains unencoded Chinese characters or spaces.

Related errors


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