This is an automated email from the ASF dual-hosted git repository.
reta pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new c9f8dc49787 Add maxFormParameterSize contextual message parameter and
bound form params processing to it (#3457)
c9f8dc49787 is described below
commit c9f8dc497879b5a2eca2a51a6d21f80966d534a1
Author: Andriy Redko <[email protected]>
AuthorDate: Thu Sep 10 18:39:41 2026 -0400
Add maxFormParameterSize contextual message parameter and bound form params
processing to it (#3457)
---
.../cxf/jaxrs/impl/HttpServletRequestFilter.java | 3 ++-
.../java/org/apache/cxf/jaxrs/utils/FormUtils.java | 5 +++++
.../org/apache/cxf/jaxrs/utils/JAXRSUtils.java | 2 +-
.../oauth2/client/ClientCodeRequestFilter.java | 7 +++++--
.../security/oidc/rp/OidcIdTokenRequestFilter.java | 7 +++++--
.../oidc/rp/OidcRpAuthenticationFilter.java | 7 +++++--
.../systest/jaxrs/JAXRSClientServerBookTest.java | 24 ++++++++++++++++++++++
7 files changed, 47 insertions(+), 8 deletions(-)
diff --git
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletRequestFilter.java
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletRequestFilter.java
index 36285ca3c71..dba00c4b156 100644
---
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletRequestFilter.java
+++
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletRequestFilter.java
@@ -119,7 +119,8 @@ public class HttpServletRequestFilter extends
HttpServletRequestWrapper {
formParams = new MetadataMap<>();
MediaType mt =
JAXRSUtils.toMediaType((String)m.get(Message.CONTENT_TYPE));
String enc = HttpUtils.getEncoding(mt,
StandardCharsets.UTF_8.name());
- String body =
FormUtils.readBody(m.getContent(InputStream.class), enc);
+ String body =
FormUtils.readBody(m.getContent(InputStream.class), enc,
+ FormUtils.getMaxFormParamsSize(m));
FormUtils.populateMapFromString(formParams, m, body, enc,
true);
}
}
diff --git
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
index 3479f737e95..fd8c5cd1fb6 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
@@ -67,6 +67,7 @@ public final class FormUtils {
private static final Logger LOG = LogUtils.getL7dLogger(FormUtils.class);
private static final String MULTIPART_FORM_DATA_TYPE = "form-data";
private static final String MAX_FORM_PARAM_COUNT = "maxFormParameterCount";
+ private static final String MAX_FORM_PARAM_SIZE = "maxFormParameterSize";
private static final String CONTENT_DISPOSITION_FILES_PARAM = "files";
private FormUtils() {
@@ -334,4 +335,8 @@ public final class FormUtils {
return
MediaType.APPLICATION_FORM_URLENCODED.equals(m.get(Message.CONTENT_TYPE))
&& HttpMethod.POST.equals(m.get(Message.HTTP_REQUEST_METHOD));
}
+
+ public static int getMaxFormParamsSize(Message m) {
+ return MessageUtils.getContextualInteger(m, MAX_FORM_PARAM_SIZE,
DEFAULT_FORM_PARAMS_MAX_SIZE);
+ }
}
diff --git
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
index d1beb0c25c8..1bcb78e7eaf 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
@@ -1198,7 +1198,7 @@ public final class JAXRSUtils {
if (mt == null ||
mt.isCompatible(MediaType.APPLICATION_FORM_URLENCODED_TYPE)) {
InputStream entityStream = copyAndGetEntityStream(m);
- String body = FormUtils.readBody(entityStream, enc);
+ String body = FormUtils.readBody(entityStream, enc,
FormUtils.getMaxFormParamsSize(m));
// Do not decode unless the key is empty value, fe
@FormParam("")
FormUtils.populateMapFromStringOrHttpRequest(params, m, body,
enc, StringUtils.isEmpty(key) && decode);
} else {
diff --git
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
index ffdf95c48cb..cbfc8bcb1e1 100644
---
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
+++
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
@@ -44,6 +44,7 @@ import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.utils.ExceptionUtils;
import org.apache.cxf.jaxrs.utils.FormUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant;
import org.apache.cxf.rs.security.oauth2.grants.code.CodeVerifierTransformer;
@@ -311,8 +312,10 @@ public class ClientCodeRequestFilter implements
ContainerRequestFilter {
MultivaluedMap<String, String> requestState = new MetadataMap<>();
requestState.putAll(ui.getQueryParameters(decodeRequestParameters));
if
(MediaType.APPLICATION_FORM_URLENCODED_TYPE.isCompatible(rc.getMediaType())) {
- String body = FormUtils.readBody(rc.getEntityStream(),
StandardCharsets.UTF_8.name());
- FormUtils.populateMapFromString(requestState,
JAXRSUtils.getCurrentMessage(), body,
+ final Message currentMessage = JAXRSUtils.getCurrentMessage();
+ String body = FormUtils.readBody(rc.getEntityStream(),
StandardCharsets.UTF_8.name(),
+ FormUtils.getMaxFormParamsSize(currentMessage));
+ FormUtils.populateMapFromString(requestState, currentMessage, body,
StandardCharsets.UTF_8.name(),
decodeRequestParameters);
}
return requestState;
diff --git
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcIdTokenRequestFilter.java
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcIdTokenRequestFilter.java
index 88b6ce62991..4d6258e581c 100644
---
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcIdTokenRequestFilter.java
+++
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcIdTokenRequestFilter.java
@@ -31,6 +31,7 @@ import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.utils.FormUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
import org.apache.cxf.rs.security.oauth2.client.Consumer;
import org.apache.cxf.rs.security.oidc.common.IdToken;
@@ -60,8 +61,10 @@ public class OidcIdTokenRequestFilter implements
ContainerRequestFilter {
private MultivaluedMap<String, String> toFormData(ContainerRequestContext
rc) {
MultivaluedMap<String, String> requestState = new MetadataMap<>();
if
(MediaType.APPLICATION_FORM_URLENCODED_TYPE.isCompatible(rc.getMediaType())) {
- String body = FormUtils.readBody(rc.getEntityStream(),
StandardCharsets.UTF_8.name());
- FormUtils.populateMapFromString(requestState,
JAXRSUtils.getCurrentMessage(), body,
+ final Message currentMessage = JAXRSUtils.getCurrentMessage();
+ String body = FormUtils.readBody(rc.getEntityStream(),
StandardCharsets.UTF_8.name(),
+ FormUtils.getMaxFormParamsSize(currentMessage));
+ FormUtils.populateMapFromString(requestState, currentMessage, body,
StandardCharsets.UTF_8.name(),
false);
rc.setEntityStream(new
ByteArrayInputStream(StringUtils.toBytesUTF8(body)));
}
diff --git
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcRpAuthenticationFilter.java
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcRpAuthenticationFilter.java
index 48aae736602..d8731639099 100644
---
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcRpAuthenticationFilter.java
+++
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcRpAuthenticationFilter.java
@@ -39,6 +39,7 @@ import org.apache.cxf.jaxrs.ext.MessageContextImpl;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.utils.FormUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
import org.apache.cxf.rs.security.jose.jwt.JwtException;
import org.apache.cxf.rs.security.jose.jwt.JwtUtils;
import org.apache.cxf.rs.security.oauth2.client.ClientTokenContext;
@@ -114,8 +115,10 @@ public class OidcRpAuthenticationFilter implements
ContainerRequestFilter {
MultivaluedMap<String, String> requestState = new MetadataMap<>();
requestState.putAll(rc.getUriInfo().getQueryParameters(true));
if
(MediaType.APPLICATION_FORM_URLENCODED_TYPE.isCompatible(rc.getMediaType())) {
- String body = FormUtils.readBody(rc.getEntityStream(),
StandardCharsets.UTF_8.name());
- FormUtils.populateMapFromString(requestState,
JAXRSUtils.getCurrentMessage(), body,
+ final Message currentMessage = JAXRSUtils.getCurrentMessage();
+ String body = FormUtils.readBody(rc.getEntityStream(),
StandardCharsets.UTF_8.name(),
+ FormUtils.getMaxFormParamsSize(currentMessage));
+ FormUtils.populateMapFromString(requestState, currentMessage, body,
StandardCharsets.UTF_8.name(),
true);
rc.setEntityStream(new
ByteArrayInputStream(StringUtils.toBytesUTF8(body)));
diff --git
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
index 4b0b1d9d498..8fb2e885b62 100644
---
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
+++
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
@@ -355,6 +355,17 @@ public class JAXRSClientServerBookTest extends
AbstractBusClientServerTestBase {
assertThat("max form params limit reached", r.getStatus(),
equalTo(413));
}
+ @Test
+ public void testTooManyFormParamsUsingForm() throws Exception {
+ // Exceeding 500 limit
+ String params = IntStream.range(0, 501).mapToObj(i -> "id" + i + "=" +
i).collect(Collectors.joining("&"));
+ String address = "http://localhost:" + PORT +
"/bookstore/formParams/1";
+ WebClient wc = WebClient.create(address);
+ wc.type(MediaType.APPLICATION_FORM_URLENCODED);
+ Response r = wc.post(new
ByteArrayInputStream(params.getBytes(StandardCharsets.UTF_8)));
+ assertThat("max form params limit reached", r.getStatus(),
equalTo(413));
+ }
+
@Test
public void testTooLargeFormParams() throws Exception {
// Exceeding 100Mb limit
@@ -368,6 +379,19 @@ public class JAXRSClientServerBookTest extends
AbstractBusClientServerTestBase {
assertThat("max form params limit reached", r.getStatus(),
equalTo(500));
}
+ @Test
+ public void testTooLargeFormParamsUsingForm() throws Exception {
+ // Exceeding 100Mb limit
+ String params = IntStream.range(0, 150)
+ .mapToObj(i -> "id" + i + "="
+ + new
String(Integer.toString(i)).repeat(524800)).collect(Collectors.joining("&"));
+ String address = "http://localhost:" + PORT +
"/bookstore/formParams/1";
+ WebClient wc = WebClient.create(address);
+ wc.type(MediaType.APPLICATION_FORM_URLENCODED);
+ Response r = wc.post(new
ByteArrayInputStream(params.getBytes(StandardCharsets.UTF_8)));
+ assertThat("max form params limit reached", r.getStatus(),
equalTo(500));
+ }
+
@Test
public void testGetBookDescriptionHttpResponse() throws Exception {
String address = "http://localhost:" + PORT +
"/bookstore/httpresponse";