lukaszlenart opened a new pull request, #1916:
URL: https://github.com/apache/struts/pull/1916

   Fixes [WW-5725](https://issues.apache.org/jira/browse/WW-5725)
   
   `AuthorizingSettableBeanProperty` authorized a property in 
`deserializeAndSet` / `deserializeSetAndReturn` and wrapped the value 
deserializer only for creator-bound properties. Jackson takes neither route for 
a non-creator property it buffers during property-based creation: a setter 
property that appears in the body before the last creator parameter is read 
through the `final` `SettableBeanProperty.deserialize()` with no authorization 
and no path push, and assigned after construction through 
`SettableBeanProperty.set()`, which the `Delegating` base forwarded unchecked. 
The same property after the last creator parameter, or on a setter-only type, 
was already rejected, so member order alone decided whether the check applied, 
and the members of a buffered bean-valued property were checked one level too 
shallow.
   
   Three gates now cover the paths between them:
   
   - `deserializeAndSet` / `deserializeSetAndReturn` keep authorizing the 
direct path and skipping the value on rejection, so the setter never fires, but 
no longer push the path themselves.
   - `AuthorizingValueDeserializer` wraps every property's value deserializer, 
not only creator properties, and owns the path push for nested members. It 
covers all three of Jackson's entry points — `deserialize(p, ctxt)`, the 
in-place `deserialize(p, ctxt, intoValue)` used for setterless collections, and 
`deserializeWithType` for polymorphic properties — and classifies the `[0]` 
element prefix on the property's declared type. On the direct path it re-checks 
a path `deserializeAndSet` already accepted; the authorizer is stateless, so 
the answer is the same.
   - `set` / `setAndReturn` authorize the already-materialized assignment, 
which also covers a buffered `null` (Jackson skips the value deserializer for a 
null token) and the other callers of `set()` in jackson-databind: `@JsonMerge`, 
`@JsonManagedReference`, inner-class valued properties, `EXTERNAL_PROPERTY` 
type ids and the `@JsonIdentityInfo` id property, none of which were authorized 
before.
   
   All gates go through `DynamicKeyAuthorizationContext`, so a dynamic-key 
scope authorizes by depth on every path.
   
   **Tests** (all in `ParameterAuthorizingModuleTest`): setter before and after 
the last creator parameter, a setter-only type with the same member order, a 
nested creator, a creator-plus-setter type inside a dynamic-key scope, a 
buffered bean-valued setter whose members must be authorized at their own 
depth, a setterless collection, and a polymorphic property. The last two are 
written in the direction that matters — a sibling grant on the enclosing bean 
must not authorize a collapsed nested path — and both failed against an 
intermediate version of this change that had moved the push but not yet covered 
the 3-arg and typed entry points.
   
   **Behaviour notes.** No configuration or API change. A request that 
previously had an unauthorized property assigned only because of its position 
in the body now has it dropped, consistent with every other position. 
Properties assigned through the other `set()` callers listed above are now 
subject to the same authorization as ordinary setters — most visibly, an 
`@JsonIdentityInfo` id property now needs `@StrutsParameter` like any other. A 
buffered rejection logs twice (once at the read, once at the assignment); the 
assignment-side warning is kept because it is the only one for the other 
`set()` callers.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
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