Lukasz Lenart created WW-5727:
---------------------------------

             Summary: The @JsonIdentityInfo id property is not authorized in 
the REST plugin
                 Key: WW-5727
                 URL: https://issues.apache.org/jira/browse/WW-5727
             Project: Struts 2
          Issue Type: Bug
          Components: Plugin - REST
            Reporter: Lukasz Lenart
             Fix For: 7.4.0


h2. Summary

On a type annotated with {{@JsonIdentityInfo}} using a property-based 
generator, the id property is assigned through Jackson's {{ObjectIdReader}}, 
which holds a reference to the property captured before 
{{ParameterAuthorizingModule}} runs. The reader writes through that original 
property, so the authorization wrapper installed by the module is never 
consulted and the id is assigned without a check.

Sibling of WW-5725 and WW-5726: a Jackson path that takes hold of the property 
before the deserializer modifier can wrap it.

h2. Current behaviour

{{BeanDeserializerFactory.buildBeanDeserializer}} calls {{addObjectIdReader}} 
before applying the deserializer modifiers. {{addObjectIdReader}} looks the id 
property up in the builder and stores it in the {{ObjectIdReader}} it 
constructs. {{ParameterAuthorizingModule.updateBuilder}} then replaces every 
property in the builder with {{AuthorizingSettableBeanProperty}}, but the 
{{ObjectIdReader}} still refers to the property it captured.

At deserialization time the {{ObjectIdValueProperty}} that Jackson adds for the 
id delegates to {{ObjectIdReader.idProperty.setAndReturn(...)}}, i.e. to the 
unwrapped property. With an authorizer that rejects {{id}}, a body of {{{"id": 
7, "name": "alice"}}} still sets {{id}} to 7 while {{name}} is handled normally.

Members of such a type other than the id are unaffected. 6.x is unaffected: the 
REST plugin there has no Jackson authorization module.

h2. Proposed change

In {{ParameterAuthorizingModule.updateBuilder}}, after the properties have been 
wrapped, check {{builder.getObjectIdReader()}}. If one is present, construct a 
replacement with {{ObjectIdReader.construct(...)}} carrying the same id type, 
property name, generator, resolver and deserializer, but with the wrapped id 
property, and set it back on the builder. The reader's fields are all available 
for that.

Add a test with a {{@JsonIdentityInfo(generator = 
ObjectIdGenerators.PropertyGenerator.class, property = "id")}} type: with 
{{id}} rejected the field must keep its default, with {{id}} granted it must be 
assigned.

h2. Compatibility notes

No configuration or API change. An id property on such a type is now subject to 
the same {{@StrutsParameter}} authorization as any other property; an 
application relying on it being bound without a grant needs to annotate it.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to