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)