Skip to content

fix(rest-plugin): enforce @StrutsParameter in JacksonJsonHandler.toObject()#1652

Open
tranquac wants to merge 1 commit intoapache:mainfrom
tranquac:fix/rest-plugin-strutsparameter-bypass
Open

fix(rest-plugin): enforce @StrutsParameter in JacksonJsonHandler.toObject()#1652
tranquac wants to merge 1 commit intoapache:mainfrom
tranquac:fix/rest-plugin-strutsparameter-bypass

Conversation

@tranquac
Copy link
Copy Markdown

@tranquac tranquac commented Apr 6, 2026

Summary

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.

Changes

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

Impact

Without this fix:

  • URL params to unannotated setters: BLOCKED (ParametersInterceptor enforces)
  • REST JSON body to same unannotated setters: BYPASSES (Jackson merge ignores annotation)

With this fix, both pathways consistently enforce @StrutsParameter.

Test

A PoC application with 9 test cases demonstrates the bypass using an OrderAction with annotated (setItemName, setQuantity) and unannotated (setUnitPrice, setDiscount, setApproved, setInternalNote) setters. JSON body sets unitPrice from 99.99 to 0.01 and approved to true before the fix.

…ject()

JacksonJsonHandler.toObject() uses ObjectMapper.readerForUpdating(target)
to merge JSON request body directly into the action object, bypassing
the @StrutsParameter annotation check that ParametersInterceptor
enforces for URL parameters. This allows mass assignment of unannotated
properties via REST JSON request body.

When struts.parameters.requireAnnotations is enabled, deserialize JSON
into a map first, then filter properties by @StrutsParameter annotation
on the target's setter methods before setting them. Only annotated
setters are populated, consistent with ParametersInterceptor behavior.

When requireAnnotations is disabled, preserve the original unrestricted
readerForUpdating() merge for backwards compatibility.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant