{"record":{"id":"57e90831fee7226c","repo":"jeecgboot/JeecgBoot","slug":"url-57e908","errorCode":null,"errorMessage":"非法URL：主机名为空","messagePattern":"非法URL：主机名为空","errorType":"validation","errorClass":"JeecgBootException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/SsrfFileTypeFilter.java","lineNumber":338,"sourceCode":"     * @param fileUrl HTTP(S) URL\n     */\n    public static void checkSsrfHttpUrl(String fileUrl) {\n        if (StringUtils.isBlank(fileUrl)) {\n            throw new JeecgBootException(\"非法URL：地址为空\");\n        }\n        URI uri;\n        try {\n            uri = new URI(fileUrl);\n        } catch (URISyntaxException e) {\n            throw new JeecgBootException(\"非法URL：格式错误\");\n        }\n        String scheme = uri.getScheme();\n        if (scheme == null || !(scheme.equalsIgnoreCase(\"http\") || scheme.equalsIgnoreCase(\"https\"))) {\n            throw new JeecgBootException(\"非法URL：仅允许 http / https 协议\");\n        }\n        String host = uri.getHost();\n        if (StringUtils.isBlank(host)) {\n            throw new JeecgBootException(\"非法URL：主机名为空\");\n        }\n        // 去掉 IPv6 的中括号\n        if (host.startsWith(\"[\") && host.endsWith(\"]\")) {\n            host = host.substring(1, host.length() - 1);\n        }\n        try {\n            for (InetAddress addr : InetAddress.getAllByName(host)) {\n                if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) {\n                    throw new JeecgBootException(\"非法URL：禁止访问本机或链路本地地址 \" + addr.getHostAddress());\n                }\n            }\n        } catch (UnknownHostException e) {\n            throw new JeecgBootException(\"非法URL：主机名无法解析\");\n        }\n    }\n    //update-end---author:zhangdaihao ---date:2026-04-15  for：【issues/9553】修复二次SSRF漏洞，对HTTP下载URL进行安全校验-----------\n\n    /**","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/SsrfFileTypeFilter.java#L320-L356","documentation":"Thrown by checkSsrfHttpUrl when the parsed URI has a null or blank host — the URL contains a valid scheme but no resolvable hostname. Without a host, the SSRF target cannot be verified, so the method refuses to proceed.","triggerScenarios":"URLs like 'http:///path' (triple slash, no host), 'http://:8080/path' (port but no host), 'http://' (scheme and // but empty host), or URLs where the host portion is all whitespace.","commonSituations":"Misconstructed URL from string concatenation where the host variable was empty (e.g., 'http://' + '' + '/api'); URL template placeholder for host was not filled; regex-based URL construction left host blank.","solutions":["Validate that the host portion of the URL is non-empty before calling checkSsrfHttpUrl.","Log the full URL at debug level when this error occurs to identify which caller constructs a hostless URL.","Add front-end validation requiring a complete URL with domain.","Check if a configuration property (e.g., MinIO endpoint, OSS host) is blank and causing the hostless URL."],"exampleFix":"// before\nString endpoint = minioConfig.getEndpoint(); // could be \"\"\nString fileUrl = endpoint + \"/\" + objectKey; // \"http:///bucket/key\"\nSsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);\n\n// after\nString endpoint = minioConfig.getEndpoint();\nif (oConvertUtils.isEmpty(endpoint)) {\n    throw new JeecgBootException(\"文件服务地址未配置\");\n}\nString fileUrl = endpoint + \"/\" + objectKey;\nSsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);","handlingStrategy":"validation","validationCode":"URI testUri = new URI(fileUrl);\nif (oConvertUtils.isEmpty(testUri.getHost())) {\n    return Result.error(\"URL缺少主机名\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    SsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);\n} catch (JeecgBootException e) {\n    log.error(\"URL has no host: {}\", fileUrl);\n    return Result.error(e.getMessage());\n}","preventionTips":["Validate that configuration properties for service endpoints (MinIO, OSS) are non-empty.","Log the full URL at debug level to diagnose hostless URLs.","Use URL builders (e.g., UriComponentsBuilder) instead of string concatenation."],"tags":["ssrf","validation","host","security","url","config"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}