{"record":{"id":"4cf9027f43207f40","repo":"jeecgboot/JeecgBoot","slug":"url-4cf902","errorCode":null,"errorMessage":"非法URL：地址为空","messagePattern":"非法URL：地址为空","errorType":"validation","errorClass":"JeecgBootException","httpStatus":null,"severity":"warning","filePath":"jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/SsrfFileTypeFilter.java","lineNumber":324,"sourceCode":"        String fileLower = filePath.toLowerCase();\n        if (fileLower.contains(\"%2e\")) {\n            throw new JeecgBootException(\"文件路径包含非法字符\");\n        }\n    }\n\n    //update-begin---author:zhangdaihao ---date:2026-04-15  for：【issues/9553】修复二次SSRF漏洞，对HTTP下载URL进行安全校验-----------\n    /**\n     * 校验HTTP(S) URL，防止SSRF攻击（最小化拦截，只挡真正危险的目标）。\n     * 规则：\n     * 1. 仅允许 http / https 协议；\n     * 2. 解析主机IP，拒绝 loopback（127.x / ::1）和 link-local（169.254.x，含云元数据 169.254.169.254 / fe80:）；\n     * 注意：RFC1918 私网段（10/172.16/192.168）允许通过，兼容企业内网 MinIO/OSS/文件服务等合法用途。\n     *\n     * @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);","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/SsrfFileTypeFilter.java#L306-L342","documentation":"Thrown by SsrfFileTypeFilter.checkSsrfHttpUrl() when the provided HTTP download URL is null, empty, or whitespace-only. This is the first guard in the SSRF protection chain (added for issues/9553) — it validates any URL the platform fetches server-side before opening a connection. The method is called from FileDownloadUtils, HttpFileToMultipartFileUtil, AiragChatServiceImpl, and WordUtil whenever the server downloads a remote resource.","triggerScenarios":"Calling checkSsrfHttpUrl with null, \"\", or a whitespace-only string; upstream callers passing a user-supplied fileUrl field that was not populated (e.g., empty form field in an online report image URL, AIRAG chat attachment, or word template image).","commonSituations":"Front-end submits an image/resource reference field that the user left blank; a JSON payload omits the url field and Java deserializes it to null; a CSV/Excel import column for URLs has an empty row that gets processed as a download URL.","solutions":["Check for blank/null URL before calling checkSsrfHttpUrl and skip the download gracefully when the field is optional.","Ensure the front-end form or API contract requires a non-empty URL for fields that trigger server-side downloads.","If the URL comes from a comma-separated batch list, filter out blank entries before iterating (as checkPathTraversalBatch already does)."],"exampleFix":"// before\nSsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);\n\n// after\nif (oConvertUtils.isNotEmpty(fileUrl)) {\n    SsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);\n}","handlingStrategy":"validation","validationCode":"if (oConvertUtils.isEmpty(fileUrl)) {\n    // skip download or return early — do not call checkSsrfHttpUrl\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    SsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);\n} catch (JeecgBootException e) {\n    log.warn(\"SSRF URL validation failed: {}\", e.getMessage());\n    return Result.error(e.getMessage());\n}","preventionTips":["Always null/blank-check user-supplied URLs before passing to checkSsrfHttpUrl.","Treat URL fields as optional in the domain model when they may be empty.","Filter blank entries from comma-separated URL lists before iterating."],"tags":["ssrf","validation","url","security","download"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}