{"record":{"id":"48be55f9333553a2","repo":"apache/shenyu","slug":"host-cannot-be-empty","errorCode":null,"errorMessage":"Host cannot be empty","messagePattern":"Host cannot be empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/UrlSecurityUtils.java","lineNumber":80,"sourceCode":"        // Only allow HTTP and HTTPS protocols\n        if (!HTTP_PROTOCOL.equals(protocol) && !HTTPS_PROTOCOL.equals(protocol)) {\n            throw new IllegalArgumentException(\"Only HTTP and HTTPS protocols are allowed\");\n        }\n\n        // Validate host for SSRF protection using the same URL parser as request execution.\n        validateHostForSSRF(parsedUrl.host(), parsedUrl.port());\n    }\n\n    /**\n     * Validate host to prevent SSRF attacks.\n     *\n     * @param host the host to validate\n     * @param port the port to validate\n     * @throws IllegalArgumentException if the host is not allowed\n     */\n    public static void validateHostForSSRF(final String host, final int port) {\n        if (Objects.isNull(host) || host.trim().isEmpty()) {\n            throw new IllegalArgumentException(\"Host cannot be empty\");\n        }\n\n        String normalizedHost = host.toLowerCase().trim();\n\n        // Check for localhost variations\n        if (isLocalhost(normalizedHost)) {\n            throw new IllegalArgumentException(\"Access to localhost is not allowed\");\n        }\n\n        // Check for private IP addresses\n        if (isPrivateOrInternalIP(normalizedHost)) {\n            throw new IllegalArgumentException(\"Access to private or internal IP addresses is not allowed\");\n        }\n\n        // Check for sensitive ports\n        if (isSensitivePort(port)) {\n            throw new IllegalArgumentException(\"Access to sensitive ports is not allowed\");\n        }","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/UrlSecurityUtils.java#L62-L98","documentation":"validateHostForSSRF is the host-level guard invoked (directly or via validateUrlForSSRF) before admin issues an outbound request. A null or blank host throws IllegalArgumentException \"Host cannot be empty\" since SSRF checks cannot proceed without a host to evaluate.","triggerScenarios":"Calling validateHostForSSRF(null, port) or with an empty/blank host string; also reachable from validateUrlForSSRF when a parsed URL somehow yields an empty host (rare, e.g. odd scheme-less inputs).","commonSituations":"Configured target addresses missing the host portion (e.g. just ':8080' or '/path'); programmatic callers assembling host/port from incomplete config or request parameters.","solutions":["Supply the actual hostname or IP of the target as the host argument.","Fix the source config so the address includes a host, not just a port or path.","Ensure callers pass parsedUrl.host() from a successfully parsed HttpUrl rather than raw substrings.","Catch IllegalArgumentException and report 'target host is required' to the user."],"exampleFix":"// before\nvalidateHostForSSRF(uri.getHost(), uri.getPort()); // getHost() may be null\n// after\nHttpUrl url = HttpUrl.parse(targetUrl);\nif (url != null && !url.host().isEmpty()) {\n    validateHostForSSRF(url.host(), url.port());\n}","handlingStrategy":"validation","validationCode":"HttpUrl parsed = HttpUrl.parse(url);\nif (parsed == null || parsed.host().trim().isEmpty()) {\n    throw new IllegalArgumentException(\"Target URL must include a host, e.g. http://backend:8080\");\n}","typeGuard":"boolean hasHost(String s) {\n    HttpUrl u = s == null ? null : HttpUrl.parse(s.trim());\n    return u != null && !u.host().trim().isEmpty();\n}","tryCatchPattern":"try {\n    UrlSecurityUtils.validateHostForSSRF(host, port);\n} catch (IllegalArgumentException e) {\n    return ResponseEntity.badRequest().body(\"Target host is required\");\n}","preventionTips":["Always pass host from a successfully parsed HttpUrl (parsedUrl.host()), never raw substrings.","Ensure configured addresses include a host, not just ':port' or '/path'.","Require host fields in forms with non-empty validation.","Validate config at startup so empty hosts fail fast."],"tags":["ssrf","host","validation","security"],"backgroundTag":"invalid-argument-value","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}