{"record":{"id":"65791a1098ae4520","repo":"spring-projects/spring-security","slug":"the-s-was-rejected-because-it-can-only-contain-pr","errorCode":null,"errorMessage":"The %s was rejected because it can only contain printable ASCII characters.","messagePattern":"The (.+?) was rejected because it can only contain printable ASCII characters\\.","errorType":"exception","errorClass":"RequestRejectedException","httpStatus":400,"severity":"error","filePath":"web/src/main/java/org/springframework/security/web/firewall/StrictHttpFirewall.java","lineNumber":529,"sourceCode":"\t\tthis.encodedUrlBlocklist.removeAll(values);\n\t\tthis.decodedUrlBlocklist.removeAll(values);\n\t}\n\n\t@Override\n\tpublic FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {\n\t\trejectForbiddenHttpMethod(request);\n\t\trejectedBlocklistedUrls(request);\n\t\trejectedUntrustedHosts(request);\n\t\tif (!isNormalized(request)) {\n\t\t\tthrow new RequestRejectedException(\"The request was rejected because the URL was not normalized.\");\n\t\t}\n\t\trejectNonPrintableAsciiCharactersInFieldName(request.getRequestURI(), \"requestURI\");\n\t\treturn new StrictFirewalledRequest(request);\n\t}\n\n\tprivate void rejectNonPrintableAsciiCharactersInFieldName(String toCheck, String propertyName) {\n\t\tif (!containsOnlyPrintableAsciiCharacters(toCheck)) {\n\t\t\tthrow new RequestRejectedException(String\n\t\t\t\t.format(\"The %s was rejected because it can only contain printable ASCII characters.\", propertyName));\n\t\t}\n\t}\n\n\tprivate void rejectForbiddenHttpMethod(HttpServletRequest request) {\n\t\tif (this.allowedHttpMethods == ALLOW_ANY_HTTP_METHOD) {\n\t\t\treturn;\n\t\t}\n\t\tif (!this.allowedHttpMethods.contains(request.getMethod())) {\n\t\t\tthrow new RequestRejectedException(\n\t\t\t\t\t\"The request was rejected because the HTTP method \\\"\" + request.getMethod()\n\t\t\t\t\t\t\t+ \"\\\" was not included within the list of allowed HTTP methods \" + this.allowedHttpMethods);\n\t\t}\n\t}\n\n\tprivate void rejectedBlocklistedUrls(HttpServletRequest request) {\n\t\tfor (String forbidden : this.encodedUrlBlocklist) {\n\t\t\tif (encodedUrlContains(request, forbidden)) {","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/web/src/main/java/org/springframework/security/web/firewall/StrictHttpFirewall.java#L511-L547","documentation":"StrictHttpFirewall rejects request fields (here the requestURI) containing characters outside the printable ASCII range (32-126). Non-printable or non-ASCII characters in URLs are typical of smuggling/ injection attempts and are never legitimate in an HTTP request line, so the firewall throws RequestRejectedException naming the rejected field via String.format.","triggerScenarios":"getFirewalledRequest delegates to rejectNonPrintableAsciiCharactersInFieldName(request.getRequestURI(), \"requestURI\") and the URI contains bytes like %00, control characters, or raw UTF-8 multibyte sequences (e.g. %E4%B8%AD decoded raw in the URI).","commonSituations":"APIs that carry user names or search terms in the path with unencoded unicode; XSS/filter-evasion probes sending %00 or newline bytes; legacy clients sending unencoded UTF-8; log-injection tooling tests; bot traffic with obfuscated URIs.","solutions":["Percent-encode non-ASCII data before putting it in the URL path (use UriComponentsBuilder.encode() or client-side encodeURIComponent)","URL-decode/encode consistently at the gateway so the request line contains only ASCII; reject or sanitize such requests at the proxy","If identifiers must be human-readable text, move them into a query parameter or request body where encoding rules differ, or use opaque IDs","Inspect access logs to identify the offending client; if it is an attacker/probe, no fix is needed — the firewall is working as intended"],"exampleFix":"// before\nString url = \"/users/\" + username; // username may contain unicode/control chars\n// after\nString url = UriComponentsBuilder.fromPath(\"/users/{username}\")\n    .buildAndExpand(username)\n    .encode().toUriString();","handlingStrategy":"validation","validationCode":"String uri = request.getRequestURI();\nboolean printableAscii = uri.chars().allMatch(c -> c >= 32 && c < 127);\nif (!printableAscii) {\n    // percent-encode before sending, or reject at the client/gateway\n}","typeGuard":null,"tryCatchPattern":"try {\n    FirewalledRequest fw = firewall.getFirewalledRequest(request);\n    chain.doFilter(fw, response);\n} catch (RequestRejectedException e) {\n    log.warn(\"Non-printable ASCII in {}: {}\", \"requestURI\", request.getRequestURI());\n    response.sendError(HttpServletResponse.SC_BAD_REQUEST);\n}","preventionTips":["Always percent-encode path parameters containing unicode or control characters","Keep user-supplied free text out of URL paths — use query params, bodies, or opaque IDs","Sanitize/validate path segments with a regex like [\\x20-\\x7E]+ before making outbound requests","Treat violations in logs as probe traffic and correlate with WAF/IP blocking rules"],"tags":["spring-security","firewall","ascii-validation","request-rejected","security"],"backgroundTag":"invalid-argument-format","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"}