[
https://issues.apache.org/jira/browse/WW-5771?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Lukasz Lenart updated WW-5771:
------------------------------
Fix Version/s: 7.5.0
> StrutsParameterAuthorizer only matches naively capitalized setters, rejecting
> annotated JavaBeans-compliant setters like seteMail
> ---------------------------------------------------------------------------------------------------------------------------------
>
> Key: WW-5771
> URL: https://issues.apache.org/jira/browse/WW-5771
> Project: Struts 2
> Issue Type: Bug
> Components: Core Interceptors
> Affects Versions: 7.4.0
> Reporter: Niklas Neesen
> Priority: Major
> Fix For: 7.5.0
>
>
> Since 7.4.0, {{StrutsParameterAuthorizer.findBindableAccessor}} resolves the
> setter for a depth-0 parameter by building the name itself:
> {code:java}
> String setterName = "set" + Character.toUpperCase(property.charAt(0)) +
> property.substring(1);
> {code}
> For a property whose name starts with a lowercase letter followed by an
> uppercase letter (e.g. {{eMail}}), this only finds the naively capitalized
> {{setEMail}}. Per the JavaBeans specification (the inverse of
> {{Introspector.decapitalize}}), the accessor for property {{eMail}} is
> {{seteMail}} — which is what 7.3.0 found via
> {{PropertyDescriptor#getWriteMethod}} and what developers annotated with
> {{@StrutsParameter}}.
> The result: an action with a correctly annotated, spec-compliant setter
> {code:java}
> private String eMail;
> @StrutsParameter
> public void seteMail(String eMail) { this.eMail = eMail; }
> {code}
> passes authorization on 7.3.0 but is rejected on 7.4.0 — the parameter is
> silently dropped (in production mode nothing is logged above debug level),
> the field stays null, and the regression surfaces only as downstream
> application errors.
> The Javadoc on {{findBindableAccessor}} says the setter is "matched the way
> OGNL matches it". That was true for OGNL 3.4.0-3.4.13, which had exactly this
> naive-capitalization bug — but it was fixed in OGNL 3.4.14
> ([https://github.com/orphan-oss/ognl/issues/643],
> [https://github.com/orphan-oss/ognl/pull/644]): OGNL now resolves both base
> names, spec-compliant first. So on current Struts 7.4.0 + OGNL 3.4.14+, the
> authorizer and the binder it guards disagree in both directions:
> * The authorizer inspects {{setEMail}} (and requires the annotation there),
> while OGNL binds through {{seteMail}}.
> * An annotation on the spec-compliant setter — the method OGNL actually
> invokes — is invisible to the authorizer.
> h3. Standalone reproducer
> Only struts2-core and ognl on the classpath:
> {code:java}
> public class Repro {
> public static class SpecCompliantAction {
> private String eMail;
> @StrutsParameter
> public void seteMail(String v) { this.eMail = v; }
> }
> public static void main(String[] args) {
> StrutsParameterAuthorizer auth = new StrutsParameterAuthorizer();
> auth.setRequireAnnotations("true");
> auth.setOgnlUtil(/* OgnlUtil with default caches */);
> auth.setProxyService(/* no-op ProxyService */);
> SpecCompliantAction a = new SpecCompliantAction();
> // 7.3.0: true — 7.4.0: false
> System.out.println(auth.isAuthorized("eMail", a, a));
> }
> }
> {code}
> Observed matrix:
> || ||annotated {{seteMail}} only||annotated {{seteMail}} + annotated alias
> {{setEMail}}||
> ||7.3.0|authorized|authorized|
> ||7.4.0|*rejected*|authorized|
> h3. Suggested fix
> Derive the candidate base names the same way OGNL >= 3.4.14 does
> ({{OgnlRuntime.accessorBaseNames}}): for a lowercase-then-uppercase property
> name, look up both {{set<property>}} and {{set<Capitalized property>}},
> spec-compliant name first, and accept an annotation on whichever method
> qualifies. The same applies to the getter lookup for nested parameters if it
> ever moves away from {{PropertyDescriptor}}s.
> Found while upgrading 7.3.0 → 7.4.0: parameters bound to properties of this
> naming pattern were silently dropped despite annotated, spec-compliant
> setters, and only annotating a naively capitalized alias setter restores them.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)