Gouri Sankar A created WW-5833:
----------------------------------

             Summary:  REST plugin authorizes nested container members one 
@StrutsParameter depth level short of ParametersInterceptor
                 Key: WW-5833
                 URL: https://issues.apache.org/jira/browse/WW-5833
             Project: Struts 2
          Issue Type: Bug
          Components: Plugin - REST
    Affects Versions: 7.4.0, 7.3.0
            Reporter: Gouri Sankar A


StrutsParameter documents that the depth is the number of periods or brackets 
in the parameter name, and StrutsParameterAuthorizer counts every '.', '[' and 
'(' in the full name. In the REST plugin, 
AuthorizingValueDeserializer.prefixForNested appends "[0]" once for a 
Collection, Map or array property, however deeply containers are nested. For 
List<List<Bean>>, Map<String, List<Bean>> and Bean[][] the members of the bean 
are authorized as items[0].secret (depth 2), where the form path authorizes 
items[0][0].secret (depth 3). The two-phase copy in ContentTypeInterceptor 
(used for content type handlers that are not authorization-aware) copies a 
container nested in a container unfiltered.

Reproduction (main): an action with a List<List<Bean>> items property annotated 
@StrutsParameter(depth = 2) on getter and setter. 
StrutsParameterAuthorizer.isAuthorized("items[0][0].secret") is false (depth 3 
> 2), but the JSON body \{"items":[[{"name":"n","secret":"S"}]]} through the 
Jackson handler binds secret = "S". Same for Map<String, List<Bean>> and 
Bean[][]. Reproduced on a running Struts Boot app with the REST plugin: POST 
/orders with that body ran the action with name = n and secret = S; with the 
fix the nested members are not bound, and with the annotation raised to depth = 
3 the same body binds them.

Scope and impact: only the members of beans held in a container that is itself 
nested in a container, and only where the developer's depth equals the shorter 
count. Scalars, beans and single-level containers are not affected. The members 
are of beans the developer already exposed. Affected versions: 
AuthorizingValueDeserializer.prefixForNested appends a single "[0]" in the 
7.3.0 and 7.4.0 tags (source inspection); that class does not exist in the 
7.2.x tags, which I did not examine. The behaviour itself was only reproduced 
on main.

Fix: prefixForNested adds one "[0]" per container level of the property type; 
the two-phase copy recurses into nested containers with path[0] (so a nested 
container of scalars is now copied rather than shared with the source object). 
Five new tests fail without the change and pass with it; the whole rest module 
passes.

Compatibility: the fix tightens authorization. A REST-only application with 
such a property annotated at the old shorter depth will, after the upgrade, 
have the members of those nested beans dropped from request bodies (WARN 
logged) until the depth is raised by one; the authorizer already requires the 
higher depth for a form parameter of that name. A release note is suggested.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to