Skip to content

WW-5829 fix(interceptor): apply parameter value filters to every value of a multi-valued parameter - #2087

Open
g0w6y wants to merge 1 commit into
apache:mainfrom
g0w6y:WW-5829-multivalue-parameter-value-filters
Open

g0w6y wants to merge 1 commit into
apache:mainfrom
g0w6y:WW-5829-multivalue-parameter-value-filters

Conversation

@g0w6y

@g0w6y g0w6y commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Fixes WW-5829

What & why

ParametersInterceptor hands only Parameter.getValue() (the first value) to ParameterValueAware.acceptableParameterValue and to the excluded/accepted value patterns, but then sets the whole String[] on the action. So ?tags=ok&tags=evil passes a filter that rejects evil, while ?tags=evil and ?tags=evil&tags=ok are rejected.

JSONInterceptor already checks every element of a JSON array (WW-4858). This checks every value of a repeated form parameter too, with one difference: JSONInterceptor drops only the bad list element, while here one rejected value rejects the whole parameter.

Change

isAcceptableParameterValue and isAcceptableParameterValueAware now check every value of a multi-valued parameter (small private helper valuesToCheck). One rejected value rejects the whole parameter, which is what already happens when the first value is rejected. Single-valued and empty parameters go through the same calls with the same argument as before.

How verified

Three tests added to ParametersInterceptorTest (excluded patterns, accepted patterns, ParameterValueAware), each covering single value, all values good, first value bad, second value bad.

  • Without the change: Tests run: 48, Failures: 3 (all three new tests: secondBad reached the stack).
  • With the change: ParametersInterceptorTest (48), ParameterAuthorizerTest (42) and StrutsParameterAnnotationTest (33) pass.
  • Also checked against a running Struts Boot app with an action implementing ParameterValueAware that rejects evil: ?tags=ok&tags=evil was accepted before (the action received [ok, evil]) and is rejected with the change; ?tags=ok&tags=fine still binds.

Not changed

  • No new configuration; value filters stay opt-in.
  • No partial filtering: a bad value does not just drop that one value (JSONInterceptor drops the bad list element; here the parameter is rejected whole, as it already is for a bad first value).
  • Parameter name checks are untouched.

Risk

Behaviour changes only for actions that configure value patterns or implement ParameterValueAware and receive repeated parameters where a later value is rejected; those requests were previously (wrongly) accepted. Cost is one extra pattern match per additional value.

…e of a multi-valued parameter

ParametersInterceptor passed only Parameter.getValue() (the first value) to
ParameterValueAware and the excluded/accepted value patterns, so a request such
as a=ok&a=evil was accepted although "evil" would have been rejected. Check each
value. Unlike JSONInterceptor, which drops only the bad list element, a single
rejected value rejects the whole parameter (as a rejected first value already
did). Single-valued and empty parameters behave as before.
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