{"record":{"id":"09afc2070d332dde","repo":"apache/shenyu","slug":"url-cannot-be-empty","errorCode":null,"errorMessage":"URL cannot be empty","messagePattern":"URL 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":52,"sourceCode":"    private static final String HTTP_PROTOCOL = \"http\";\n\n    private static final String HTTPS_PROTOCOL = \"https\";\n\n    /**\n     * Private constructor to prevent instantiation.\n     */\n    private UrlSecurityUtils() {\n    }\n\n    /**\n     * Validate URL to prevent SSRF attacks.\n     *\n     * @param url the URL to validate\n     * @throws IllegalArgumentException if the URL is not safe for external requests\n     */\n    public static void validateUrlForSSRF(final String url) {\n        if (Objects.isNull(url) || url.trim().isEmpty()) {\n            throw new IllegalArgumentException(\"URL cannot be empty\");\n        }\n\n        HttpUrl parsedUrl = HttpUrl.parse(url);\n        if (Objects.isNull(parsedUrl)) {\n            throw new IllegalArgumentException(\"Invalid URL format\");\n        }\n\n        String protocol = parsedUrl.scheme();\n\n        // 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","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/UrlSecurityUtils.java#L34-L70","documentation":"UrlSecurityUtils.validateUrlForSSRF performs SSRF (Server-Side Request Forgery) validation on URLs that shenyu-admin will request. If the URL string is null, empty, or whitespace-only it throws IllegalArgumentException \"URL cannot empty\" before any parsing occurs.","triggerScenarios":"Calling validateUrlForSSRF(null), validateUrlForSSRF(\"\"), or a blank/whitespace string — typically when a URL config field was never filled in or the value was lost in upstream parsing.","commonSituations":"Health-check or webhook target URLs left blank in the admin dashboard; environment/config placeholders not substituted (e.g. '${TARGET_URL}' unresolved or empty); splitting logic producing an empty string.","solutions":["Provide a complete URL (including scheme) in the configuration field or API call.","Validate/require the URL input at the form/config level before reaching the request pipeline.","Check upstream variable substitution — an unresolved placeholder may yield an empty string.","Catch IllegalArgumentException and return a clear 'target URL is required' validation message."],"exampleFix":"// before\nvalidateUrlForSSRF(config.getTargetUrl()); // may be null/empty\n// after\nif (config.getTargetUrl() == null || config.getTargetUrl().isBlank()) {\n    throw new IllegalArgumentException(\"Target URL must be configured\");\n}\nvalidateUrlForSSRF(config.getTargetUrl());","handlingStrategy":"validation","validationCode":"String url = config.getTargetUrl();\nif (url == null || url.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"Target URL must be configured and non-empty\");\n}","typeGuard":"boolean hasUrl(String s) { return s != null && !s.trim().isEmpty(); }","tryCatchPattern":"try {\n    UrlSecurityUtils.validateUrlForSSRF(url);\n} catch (IllegalArgumentException e) {\n    return ResponseEntity.badRequest().body(\"Target URL is required\");\n}","preventionTips":["Require URL fields in admin forms with non-empty validation.","Watch for unresolved placeholders (${VAR}) which often collapse to empty strings.","Validate config at startup so missing URLs fail fast, not at request time.","Trim user input before persisting it as the configured URL."],"tags":["ssrf","url","validation","security"],"backgroundTag":"empty-required-field","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"}