{"record":{"id":"d6d185bc936fce42","repo":"spring-projects/spring-security","slug":"the-request-was-rejected-because-the-domain-hostn","errorCode":null,"errorMessage":"The request was rejected because the domain <hostName> is untrusted.","messagePattern":"The request was rejected because the domain <hostName> is untrusted\\.","errorType":"exception","errorClass":"ServerExchangeRejectedException","httpStatus":400,"severity":"error","filePath":"web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java","lineNumber":603,"sourceCode":"\t\t\tif (encodedUrlContains(request, forbidden)) {\n\t\t\t\tthrow new ServerExchangeRejectedException(\n\t\t\t\t\t\t\"The request was rejected because the URL contained a potentially malicious String \\\"\"\n\t\t\t\t\t\t\t\t+ forbidden + \"\\\"\");\n\t\t\t}\n\t\t}\n\t\tfor (String forbidden : this.decodedUrlBlocklist) {\n\t\t\tif (decodedUrlContains(request, forbidden)) {\n\t\t\t\tthrow new ServerExchangeRejectedException(\n\t\t\t\t\t\t\"The request was rejected because the URL contained a potentially malicious String \\\"\"\n\t\t\t\t\t\t\t\t+ forbidden + \"\\\"\");\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void rejectedUntrustedHosts(ServerHttpRequest request) {\n\t\tString hostName = request.getURI().getHost();\n\t\tif (hostName != null && !this.allowedHostnames.test(hostName)) {\n\t\t\tthrow new ServerExchangeRejectedException(\n\t\t\t\t\t\"The request was rejected because the domain \" + hostName + \" is untrusted.\");\n\t\t}\n\t}\n\n\tprivate static Set<HttpMethod> createDefaultAllowedHttpMethods() {\n\t\tSet<HttpMethod> result = new HashSet<>();\n\t\tresult.add(HttpMethod.DELETE);\n\t\tresult.add(HttpMethod.GET);\n\t\tresult.add(HttpMethod.HEAD);\n\t\tresult.add(HttpMethod.OPTIONS);\n\t\tresult.add(HttpMethod.PATCH);\n\t\tresult.add(HttpMethod.POST);\n\t\tresult.add(HttpMethod.PUT);\n\t\treturn result;\n\t}\n\n\tprivate boolean isNormalized(ServerHttpRequest request) {\n\t\tif (!isNormalized(request.getPath().value())) {","sourceCodeStart":585,"sourceCodeEnd":621,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java#L585-L621","documentation":"The firewall extracts the Host from the request URI and tests it against the configured allowedHostnames predicate. If the host is not allowed, the request is rejected with ServerExchangeRejectedException. This defends against host-header injection and cache-poisoning attacks.","triggerScenarios":"A request arrives whose Host header (request.getURI().getHost()) fails the allowedHostnames predicate — e.g. firewall with no allowedHostnames configured (or a restrictive allowlist) receiving Host: <hostName> from a client, load balancer, or direct IP access.","commonSituations":"Accessing the app via localhost/IP/cluster-internal DNS while the allowlist only contains the public domain; forgetting to call setAllowedHostnames on the StrictServerWebExchangeFirewall bean; new staging environments with different hostnames; attackers probing with forged Host headers (correctly blocked).","solutions":["Configure the firewall's allowedHostnames to include every legitimate hostname: firewall.setAllowedHostnames(hostname -> allowedSet.contains(hostname)).","Add the new environment's hostname (staging/internal DNS) to the allowlist in configuration.","Fix proxy/load-balancer settings that pass through the wrong Host header (use proxy_set_header Host $host).","If intentional probing, block the client and ignore the rejection."],"exampleFix":"// before: no host check configured, default rejects everything unusual\nStrictServerWebExchangeFirewall firewall = new StrictServerWebExchangeFirewall();\n// after\nfirewall.setAllowedHostnames(host ->\n    host.equals(\"example.com\") || host.equals(\"staging.example.com\"));","handlingStrategy":"validation","validationCode":"Set<String> allowed = Set.of(\"example.com\", \"staging.example.com\");\nboolean isHostAllowed(String host) {\n    return host != null && allowed.contains(host.toLowerCase());\n}","typeGuard":null,"tryCatchPattern":"try {\n    exchange = firewall.getFirewalledExchange(exchange);\n} catch (ServerExchangeRejectedException e) {\n    log.warn(\"Untrusted host rejected: {}\", e.getMessage());\n    return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();\n}","preventionTips":["Explicitly set setAllowedHostnames with every environment's hostname (dev, staging, prod).","Include localhost/IP variants only in non-production profiles.","Ensure load balancers preserve the original Host header.","Add a startup check that logs the configured host allowlist."],"tags":["security","spring-security","host-header","firewall"],"backgroundTag":"invalid-config-value","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}