Describe the bug
The FormFilter incorrectly handles POST requests with URL-encoded parameters in the query string, causing double encoding and parameter duplication.
Reproduction Steps
- Start a gateway server with the following route configuration:
@SpringBootApplication
public class GatewayServer {
public static void main(String[] args) {
SpringApplication.run(GatewayServer.class, args);
}
@Bean
public RouterFunction<ServerResponse> getRoute() {
return route()
.POST("/anything", http("https://httpbin.org"))
.build();
}
}
- Send a POST request to the gateway server:
curl -X POST "http://localhost:8080/anything?foo=%7B%7D" \
-H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"
Expected vs. Actual Behavior
Expected request sent to upstream:
POST /anything?foo=%7B%7D HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
<empty body>
Actual request sent to upstream:
POST /anything?foo=%257B%257D HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
foo=%7B%7D
Root Cause
The issue stems from a mismatch in parameter handling:
HttpServletRequest#getParameterMap() returns parameters that have already been URL-decoded by the servlet container
- The existing
queryParams contains raw (non-decoded) parameters
- This causes the filter to incorrectly process the parameters, resulting in double encoding (
%7B%7D becomes %257B%257D) and duplication of parameters in the request body
|
Map<String, String[]> form = request.getParameterMap(); |
|
String queryString = request.getQueryString(); |
|
StringBuffer requestURL = request.getRequestURL(); |
|
if (StringUtils.hasText(queryString)) { |
|
requestURL.append('?').append(queryString); |
|
} |
|
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(requestURL.toString()); |
|
MultiValueMap<String, String> queryParams = uriComponentsBuilder.build().getQueryParams(); |
Solution
I will submit a pull request to address this parameter handling inconsistency in the FormFilter.
Describe the bug
The
FormFilterincorrectly handles POST requests with URL-encoded parameters in the query string, causing double encoding and parameter duplication.Reproduction Steps
Expected vs. Actual Behavior
Expected request sent to upstream:
Actual request sent to upstream:
Root Cause
The issue stems from a mismatch in parameter handling:
HttpServletRequest#getParameterMap()returns parameters that have already been URL-decoded by the servlet containerqueryParamscontains raw (non-decoded) parameters%7B%7Dbecomes%257B%257D) and duplication of parameters in the request bodyspring-cloud-gateway/spring-cloud-gateway-server-webmvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/FormFilter.java
Lines 115 to 122 in 4b3a434
Solution
I will submit a pull request to address this parameter handling inconsistency in the
FormFilter.