{"record":{"id":"908ff132f72f054c","repo":"pinpoint-apm/pinpoint","slug":"webhook-url-scheme-must-be-http-or-https","errorCode":null,"errorMessage":"Webhook URL scheme must be http or https","messagePattern":"Webhook URL scheme must be http or https","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"commons-server/src/main/java/com/navercorp/pinpoint/common/server/webhook/WebhookUrlValidator.java","lineNumber":114,"sourceCode":"        } catch (URISyntaxException e) {\n            throw new IllegalArgumentException(\"Malformed webhook URL\", e);\n        }\n\n        validateScheme(uri);\n        validateAuthority(uri);\n\n        return uri;\n    }\n\n    private static void validateScheme(URI uri) {\n        String scheme = uri.getScheme();\n        if (scheme == null) {\n            throw new IllegalArgumentException(\"Webhook URL scheme is required\");\n        }\n\n        String normalizedScheme = scheme.toLowerCase(Locale.ROOT);\n        if (!\"http\".equals(normalizedScheme) && !\"https\".equals(normalizedScheme)) {\n            throw new IllegalArgumentException(\"Webhook URL scheme must be http or https\");\n        }\n    }\n\n    private static void validateAuthority(URI uri) {\n        if (uri.getHost() == null || uri.getHost().isBlank()) {\n            throw new IllegalArgumentException(\"Webhook URL host is required\");\n        }\n        if (isBlockedHostLiteral(uri.getHost())) {\n            throw new IllegalArgumentException(\"Webhook URL host is not allowed\");\n        }\n        if (uri.getRawUserInfo() != null) {\n            throw new IllegalArgumentException(\"Webhook URL user info is not allowed\");\n        }\n        if (uri.getRawFragment() != null) {\n            throw new IllegalArgumentException(\"Webhook URL fragment is not allowed\");\n        }\n        int port = uri.getPort();\n        if (port == -1 && hasExplicitPort(uri)) {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/commons-server/src/main/java/com/navercorp/pinpoint/common/server/webhook/WebhookUrlValidator.java#L96-L132","documentation":"WebhookUrlValidator.validateScheme throws IllegalArgumentException when the URL scheme is present but is neither http nor https (case-insensitive). The validator only permits HTTP(S) webhook targets for security reasons.","triggerScenarios":"Passing URLs like 'ftp://example.com', 'file:///etc/passwd', 'gopher://...', or 'javascript:alert(1)' to validateSyntax/uri.","commonSituations":"SSRF/protocol hardening: someone configured a file:// or custom-scheme URL; misconfigured internal endpoints using unsupported schemes; malicious input attempting scheme-based attacks.","solutions":["Change the webhook URL to use https:// (or http:// for plain internal networks)","If a non-HTTP protocol was intended, use a component that supports it — this validator only accepts http/https","Keep the restriction: https is recommended to protect webhook payload confidentiality"],"exampleFix":"// before\nvalidator.validateSyntax(\"ftp://example.com/hook\");\n// after\nvalidator.validateSyntax(\"https://example.com/hook\");","handlingStrategy":"validation","validationCode":"java.net.URI u = java.net.URI.create(url); String s = u.getScheme(); if (s == null || !(s.equalsIgnoreCase(\"http\") || s.equalsIgnoreCase(\"https\"))) reject(url);","typeGuard":"boolean isHttpScheme(java.net.URI uri) { String s = uri.getScheme(); return \"http\".equalsIgnoreCase(s) || \"https\".equalsIgnoreCase(s); }","tryCatchPattern":"try { WebhookUrlValidator.validateSyntax(url); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"http or https\")) { reject non-HTTPS scheme; } }","preventionTips":["Restrict webhook inputs to https:// in the UI","Treat rejection of file:/ftp:/javascript: schemes as expected security behavior","Prefer https in production to protect payload confidentiality"],"tags":["java","webhook","url","security","ssrf"],"backgroundTag":"invalid-url-format","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}