g0w6y opened a new pull request, #1774: URL: https://github.com/apache/struts/pull/1774
## Summary `ParameterAuthorizingModule` enforces `@StrutsParameter` on REST/JSON body deserialization by wrapping each Jackson property's `deserializeAndSet` / `deserializeSetAndReturn` (`AuthorizingSettableBeanProperty`). Jackson never calls either method for **creator-bound properties** — Java `record`s, `@JsonCreator` constructors, `@ConstructorProperties` — it instead calls `SettableBeanProperty#deserialize` directly, which Jackson declares `final`, so the existing wrapper cannot intercept it. Practical effect: with `struts.parameters.requireAnnotations` enabled, any `record`-typed field anywhere in a REST action's request body (top-level or nested) is populated with **no `@StrutsParameter` check at all**, silently defeating the protection for that entire subtree. This is easy to hit unintentionally — `record` is the idiomatic way to model immutable REST DTOs on the Java versions Struts now targets. Verified with a live reproduction before writing the fix: a `record` field with an unauthorized component was populated anyway; after the fix, the same component is correctly rejected while an authorized sibling component still passes through. ## Fix Add `AuthorizingValueDeserializer`, which wraps the property's *value deserializer* rather than the `SettableBeanProperty` — the value deserializer is what the final `deserialize()` method delegates to, so wrapping it is the only available interception point for the creator-bound path. It is installed from `AuthorizingSettableBeanProperty#withValueDeserializer`, scoped to `CreatorProperty` specifically, so ordinary setter/field/builder-pattern properties — already correctly authorized via the existing `deserializeAndSet`/`deserializeSetAndReturn` overrides — are not checked a second time (which would also double-push the path-authorization stack and produce incorrect nested paths). ## Test plan - [x] New regression test `testRecordComponentAuthorizedByPath` in `ParameterAuthorizingModuleTest`: a `record`-typed nested property with one authorized and one unauthorized component — confirms the unauthorized component is rejected and the authorized one still deserializes. - [x] Full existing `ParameterAuthorizingModuleTest` suite (setter, builder, nested, collection, map, array authorization paths) passes unchanged — confirms no regression from scoping the new check to creator-bound properties only. - [x] Full `struts2-rest-plugin` module test suite passes (106/106). -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
