jeecgboot/JeecgBoot · critical · JeecgBootException
非法URL:禁止访问本机或链路本地地址 {hostAddress}
Error message
非法URL:禁止访问本机或链路本地地址 {hostAddress} What it means
Thrown by checkSsrfHttpUrl when InetAddress.getAllByName(host) resolves to a loopback address (127.x.x.x, ::1) or a link-local address (169.254.x.x including cloud metadata endpoint 169.254.169.254, or fe80:: IPv6). This is the core SSRF defense — it prevents the server from fetching attacker-controlled URLs that point to internal services or cloud metadata. The thrown message includes the resolved IP address for diagnostics. Note: RFC1918 private ranges (10.x, 172.16.x, 192.168.x) are intentionally allowed to support enterprise MinIO/OSS.
Source
Thrown at jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/SsrfFileTypeFilter.java:347
} 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());
}
}
} catch (UnknownHostException e) {
throw new JeecgBootException("非法URL:主机名无法解析");
}
}
//update-end---author:zhangdaihao ---date:2026-04-15 for:【issues/9553】修复二次SSRF漏洞,对HTTP下载URL进行安全校验-----------
/**
* 批量校验文件路径安全性(逗号分隔的多个文件路径)
* @param files 逗号分隔的文件路径
*/
public static void checkPathTraversalBatch(String files) {
if (StringUtils.isBlank(files)) {
return;
}
for (String file : files.split(",")) {
if (StringUtils.isNotBlank(file)) {View on GitHub (pinned to 96fb33f5ec)
Solutions
- Use the actual external hostname or IP of the target service, not 'localhost' or '127.0.0.1'.
- If downloading from a service on the same machine in production, use its LAN IP (e.g., 192.168.x.x) which is allowed.
- For cloud deployments, ensure the download URL points to the public-facing endpoint, not the internal metadata IP.
- Review the thrown IP address in the error message to identify which internal target was requested.
Example fix
// before String fileUrl = "http://localhost:9000/bucket/file.pdf"; SsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl); // throws: 127.0.0.1 // after String fileUrl = "http://192.168.1.100:9000/bucket/file.pdf"; SsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl); // passes (RFC1918 allowed)
Defensive patterns
Strategy: validation
Validate before calling
URI uri = new URI(fileUrl);
String host = uri.getHost();
for (InetAddress addr : InetAddress.getAllByName(host)) {
if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) {
return Result.error("禁止访问内部地址: " + addr.getHostAddress());
}
} Try / catch
try {
SsrfFileTypeFilter.checkSsrfHttpUrl(fileUrl);
} catch (JeecgBootException e) {
log.error("SSRF attempt blocked — loopback/link-local target in URL: {}", fileUrl);
return Result.error(e.getMessage());
} Prevention
- Use external hostnames or RFC1918 IPs (allowed) for same-network services — never localhost/127.0.0.1.
- In cloud deployments, audit all server-side fetch URLs to ensure none target metadata endpoints.
- Treat this error as a potential security incident — investigate the source of the URL.
When it happens
Trigger: URL host is 'localhost' or '127.0.0.1' (resolves to loopback); URL uses '169.254.169.254' (AWS/GCP/Azure cloud metadata endpoint); URL host is '0.0.0.0' or '::1'; DNS rebinding attack where a domain initially resolves to a public IP but resolves to 127.0.0.1 on the server's lookup.
Common situations: Developer testing with 'http://localhost:8080/...' as a download URL; misconfigured service URL pointing to loopback; SSRF attack payload targeting cloud metadata for credential theft; legitimate local development environment where the download target is on the same machine.
Related errors
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/0ab85a090594a663.
Report an issue: GitHub.