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]

Reply via email to