Lukasz Lenart created WW-5705:
---------------------------------

             Summary: StringIndexOutOfBoundsException authorizing a parameter 
name that begins with a nesting character
                 Key: WW-5705
                 URL: https://issues.apache.org/jira/browse/WW-5705
             Project: Struts 2
          Issue Type: Bug
    Affects Versions: 7.2.1, 7.3.0
            Reporter: Lukasz Lenart
             Fix For: 7.4.0


{{StrutsParameterAuthorizer#isAuthorized}} derives the root property of a 
parameter name by cutting at the first nesting character ({{.}}, {{[}} or 
{{(}}), then lower-cases its first character:

{code:java}
int nestingIndex = indexOfAny(parameterName, NESTING\_CHARS\_STR);
String rootProperty = nestingIndex == -1 ? parameterName : 
parameterName.substring(0, nestingIndex);
String normalisedRootProperty = Character.toLowerCase(rootProperty.charAt(0)) + 
rootProperty.substring(1);
{code}

When the name _begins_ with a nesting character, {{nestingIndex}} is 0, 
{{substring(0, 0)}} yields an empty string, and {{charAt(0)}} throws 
{{StringIndexOutOfBoundsException}}. The exception escapes the interceptor.

h4. Reachability
* {{ParametersInterceptor}} is *not* affected: {{isAcceptableName()}} applies 
{{ACCEPTED\_PATTERNS}}, which requires a leading {{\w+}}, before authorization.
* The JSON plugin *is*: {{JSONInterceptor}} authorizes at 
{{isAcceptableNode()}}, whereas the accepted-pattern check runs later, in 
{{isAcceptableLeafName()}}, and only for leaf keys.
* The REST plugin's {{ContentTypeInterceptor}} authorizes body-derived paths 
with no accepted- or excluded-pattern check beforehand.

Reproduced with the container's own {{StrutsParameterAuthorizer}}, under the 
shipped default {{struts.parameters.requireAnnotations=true}}, with a JSON body 
of {{{}{".foo":"x"}{}}} - the exception escapes {{JSONInterceptor.intercept()}}.

h4. Affected versions

The expression dates from WW-5352 (6.4.0), but nothing reached it with such a 
name until WW-5624 wired the JSON and REST body channels through the authorizer 
in 7.2.0.

6.x is not affected: {{requireAnnotations}} has no default there, there is no 
{{ParameterAuthorizer}} at all, and {{ParametersInterceptor}} - its only caller 
- filters names through the accepted patterns first.

h4. Impact

A failed request. No authorization bypass, no amplification, nothing persists 
beyond the single request. Triaged as an ordinary robustness bug rather than a 
vulnerability.

h4. Fix

A name beginning with a nesting character names no root property, so 
authorization rejects it before normalisation rather than computing one.

The change is already included in the WW-5698 pull request 
https://github.com/apache/struts/pull/1872 (commit {{2f3ce9601}}), since that 
PR routes ModelDriven parameters through the same expression. It can be split 
into its own PR if the release notes should attribute it separately.



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

Reply via email to