[ 
https://issues.apache.org/jira/browse/WW-5624?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Tran Quac updated WW-5624:
--------------------------
    Description: 
h2. Summary

{{JSONPopulator.populateObject()}} in the struts2-json-plugin sets action 
properties via direct Java reflection ({{{}Method.invoke(){}}}) without 
checking the {{@StrutsParameter}} annotation. This bypasses the parameter 
allowlisting that {{ParametersInterceptor}} enforces for URL parameters, 
enabling mass assignment of unannotated properties via JSON request body.

{{JacksonJsonHandler.toObject()}} in the struts2-rest-plugin uses 
{{ObjectMapper.readerForUpdating(target).readValue(reader)}} to merge JSON 
request body directly into the action object. Jackson sets any field with a 
matching setter, completely bypassing the {{@StrutsParameter}} annotation check 
that {{ParametersInterceptor}} enforces for URL parameters. This enables mass 
assignment of unannotated properties via REST JSON request body.
h2. Changes
 * {*}JSONPopulator.java{*}: Add {{@StrutsParameter}} annotation check before 
{{{}Method.invoke(){}}}. When {{struts.parameters.requireAnnotations}} is 
enabled and the setter lacks the annotation, the property is skipped with a 
debug log message.
 * {*}JSONInterceptor.java{*}: Wire the 
{{struts.parameters.requireAnnotations}} setting via {{@Inject}} into 
{{{}JSONPopulator.setRequireAnnotations(){}}}.
 * {*}JacksonJsonHandler.java{*}: When {{struts.parameters.requireAnnotations}} 
is enabled, deserialize JSON into a map first, then filter properties against 
the {{@StrutsParameter}} annotation on the target class's setter methods before 
setting them. When disabled, preserve the original {{readerForUpdating()}} 
merge for backwards compatibility.

h2. Impact

Without this fix:
 * URL params to unannotated setters: *BLOCKED* (ParametersInterceptor enforces)
 * JSON body to same unannotated setters: *BYPASSES* (JSONPopulator ignores 
annotation)

With this fix, both pathways consistently enforce {{{}@StrutsParameter{}}}.
h2. REFER

[https://github.com/apache/struts/pull/1651]

[https://github.com/apache/struts/pull/1652]

[https://github.com/apache/struts/pull/1651/changes/03a07b871ac82d8955b310155b3cbe1e30c861b3]

https://github.com/apache/struts/pull/1652/changes/d4b01caded8453bc3d02bd6ecff72e264dc81dd0

  was:
h2. Summary

{{JSONPopulator.populateObject()}} in the struts2-json-plugin sets action 
properties via direct Java reflection ({{{}Method.invoke(){}}}) without 
checking the {{@StrutsParameter}} annotation. This bypasses the parameter 
allowlisting that {{ParametersInterceptor}} enforces for URL parameters, 
enabling mass assignment of unannotated properties via JSON request body.

{{JacksonJsonHandler.toObject()}} in the struts2-rest-plugin uses 
{{ObjectMapper.readerForUpdating(target).readValue(reader)}} to merge JSON 
request body directly into the action object. Jackson sets any field with a 
matching setter, completely bypassing the {{@StrutsParameter}} annotation check 
that {{ParametersInterceptor}} enforces for URL parameters. This enables mass 
assignment of unannotated properties via REST JSON request body.
h2. Changes
 * {*}JSONPopulator.java{*}: Add {{@StrutsParameter}} annotation check before 
{{{}Method.invoke(){}}}. When {{struts.parameters.requireAnnotations}} is 
enabled and the setter lacks the annotation, the property is skipped with a 
debug log message.
 * {*}JSONInterceptor.java{*}: Wire the 
{{struts.parameters.requireAnnotations}} setting via {{@Inject}} into 
{{{}JSONPopulator.setRequireAnnotations(){}}}.
 * {*}JacksonJsonHandler.java{*}: When {{struts.parameters.requireAnnotations}} 
is enabled, deserialize JSON into a map first, then filter properties against 
the {{@StrutsParameter}} annotation on the target class's setter methods before 
setting them. When disabled, preserve the original {{readerForUpdating()}} 
merge for backwards compatibility.

h2. Impact

Without this fix:
 * URL params to unannotated setters: *BLOCKED* (ParametersInterceptor enforces)
 * JSON body to same unannotated setters: *BYPASSES* (JSONPopulator ignores 
annotation)

With this fix, both pathways consistently enforce {{{}@StrutsParameter{}}}.


> @StrutsParameter bypass
> -----------------------
>
>                 Key: WW-5624
>                 URL: https://issues.apache.org/jira/browse/WW-5624
>             Project: Struts 2
>          Issue Type: Bug
>            Reporter: Tran Quac
>            Priority: Major
>
> h2. Summary
> {{JSONPopulator.populateObject()}} in the struts2-json-plugin sets action 
> properties via direct Java reflection ({{{}Method.invoke(){}}}) without 
> checking the {{@StrutsParameter}} annotation. This bypasses the parameter 
> allowlisting that {{ParametersInterceptor}} enforces for URL parameters, 
> enabling mass assignment of unannotated properties via JSON request body.
> {{JacksonJsonHandler.toObject()}} in the struts2-rest-plugin uses 
> {{ObjectMapper.readerForUpdating(target).readValue(reader)}} to merge JSON 
> request body directly into the action object. Jackson sets any field with a 
> matching setter, completely bypassing the {{@StrutsParameter}} annotation 
> check that {{ParametersInterceptor}} enforces for URL parameters. This 
> enables mass assignment of unannotated properties via REST JSON request body.
> h2. Changes
>  * {*}JSONPopulator.java{*}: Add {{@StrutsParameter}} annotation check before 
> {{{}Method.invoke(){}}}. When {{struts.parameters.requireAnnotations}} is 
> enabled and the setter lacks the annotation, the property is skipped with a 
> debug log message.
>  * {*}JSONInterceptor.java{*}: Wire the 
> {{struts.parameters.requireAnnotations}} setting via {{@Inject}} into 
> {{{}JSONPopulator.setRequireAnnotations(){}}}.
>  * {*}JacksonJsonHandler.java{*}: When 
> {{struts.parameters.requireAnnotations}} is enabled, deserialize JSON into a 
> map first, then filter properties against the {{@StrutsParameter}} annotation 
> on the target class's setter methods before setting them. When disabled, 
> preserve the original {{readerForUpdating()}} merge for backwards 
> compatibility.
> h2. Impact
> Without this fix:
>  * URL params to unannotated setters: *BLOCKED* (ParametersInterceptor 
> enforces)
>  * JSON body to same unannotated setters: *BYPASSES* (JSONPopulator ignores 
> annotation)
> With this fix, both pathways consistently enforce {{{}@StrutsParameter{}}}.
> h2. REFER
> [https://github.com/apache/struts/pull/1651]
> [https://github.com/apache/struts/pull/1652]
> [https://github.com/apache/struts/pull/1651/changes/03a07b871ac82d8955b310155b3cbe1e30c861b3]
> https://github.com/apache/struts/pull/1652/changes/d4b01caded8453bc3d02bd6ecff72e264dc81dd0



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

Reply via email to