This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch docs/struts-7.3.0-content-audit in repository https://gitbox.apache.org/repos/asf/struts-site.git
commit dc4f6977dead23b2b484e337a972e1fd24d48399 Author: Lukasz Lenart <[email protected]> AuthorDate: Mon Aug 3 07:35:08 2026 +0200 docs: document @StrutsParameter enforcement on creator-bound REST body properties WW-5642: constructor-bound properties (Java records, @JsonCreator, @ConstructorProperties) bypassed the REST plugin's authorization wrapper up to 7.2.1, so with struts.parameters.requireAnnotations enabled they were populated unchecked. Struts 7.3.0 authorizes them by path and redacts unauthorized values, which means actions relying on unannotated record binding must now authorize those properties explicitly. Co-Authored-By: Claude Opus 5 <[email protected]> --- source/core-developers/struts-parameter-annotation.md | 19 +++++++++++++++++++ source/plugins/rest/index.md | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/source/core-developers/struts-parameter-annotation.md b/source/core-developers/struts-parameter-annotation.md index 97e3c37ff..01bc768f2 100644 --- a/source/core-developers/struts-parameter-annotation.md +++ b/source/core-developers/struts-parameter-annotation.md @@ -29,6 +29,25 @@ channel that can populate an action from request data: - [JSON](../../plugins/json) and [REST](../../plugins/rest) plugins — per-property authorization performed during deserialization, so unauthorized fields are never set. +### Creator-bound properties (records, `@JsonCreator`) + +Up to Struts 7.2.1 the REST plugin's authorization wrapper covered only properties Jackson populates through a setter, +a field or a builder. Properties bound through a **constructor** — Java records, `@JsonCreator` constructors and +`@ConstructorProperties` — were deserialized on a path that bypassed the wrapper entirely, so with +`struts.parameters.requireAnnotations` enabled a record-typed value anywhere in a REST request body was populated with +no authorization check at all. This is fixed in Struts 7.3.0, see +[WW-5642](https://issues.apache.org/jira/browse/WW-5642). + +Creator-bound properties are now authorized like any other property, by their path. Values that are not authorized are +redacted — the component is left unset rather than taking the client-supplied value — and if a record's own constructor +rejects that (a compact constructor calling `Objects.requireNonNull`, or `FAIL_ON_NULL_FOR_PRIMITIVES`), the whole +object under construction is dropped instead of failing the request. + +If a REST action relied on record-typed request-body properties binding without annotations, they now need authorizing +the same way as any nested object: `@StrutsParameter(depth = ...)` on the getter that reaches them, or a `ModelDriven` +model. Otherwise those values silently stop arriving. +{:.alert .alert-warning} + ## ModelDriven actions When an action implements `ModelDriven` and the [Model Driven diff --git a/source/plugins/rest/index.md b/source/plugins/rest/index.md index ba7790930..a830ee4e3 100644 --- a/source/plugins/rest/index.md +++ b/source/plugins/rest/index.md @@ -327,6 +327,12 @@ same property-level authorization should implement `AuthorizationAwareContentTypeHandler` (which extends `ContentTypeHandler` with authorization callbacks) instead of `ContentTypeHandler` directly. +Since Struts 7.3.0 that enforcement also covers **constructor-bound** properties — Java records, `@JsonCreator` +constructors and `@ConstructorProperties` — which previously bypassed it. If your controllers accept records in the +request body, make sure they are reachable from an authorized property; see +[Creator-bound properties](../../core-developers/struts-parameter-annotation.html#creator-bound-properties-records-jsoncreator). +{:.alert .alert-warning} + ### Settings The following settings can be customized. See the [developer guide](/core-developers/configuration-files).
