VYPR
High severityNVD Advisory· Published Sep 30, 2013· Updated Apr 29, 2026

CVE-2013-4316

CVE-2013-4316

Description

Apache Struts 2.0.0 through 2.3.15.1 enables Dynamic Method Invocation by default, which has unknown impact and attack vectors.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.struts:struts2-coreMaven
>= 2.0.0, < 2.3.15.22.3.15.2
org.apache.struts:struts2-rest-pluginMaven
>= 2.0.0, < 2.3.15.22.3.15.2

Affected products

55
  • Apache/Struts45 versions
    cpe:2.3:a:apache:struts:2.0.0:*:*:*:*:*:*:*+ 44 more
    • cpe:2.3:a:apache:struts:2.0.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.10:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.11:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.11.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.11.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.12:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.13:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.14:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.4:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.5:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.6:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.7:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.8:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.0.9:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.1.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.1.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.1.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.1.4:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.1.5:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.1.6:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.1.8:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.1.8.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.2.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.2.1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.2.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.2.3.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.1.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.12:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.14:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.14.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.14.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.14.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.15:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.15.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.4:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.4.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.7:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:struts:2.3.8:*:*:*:*:*:*:*
  • cpe:2.3:a:oracle:flexcube_private_banking:12.0.1:*:*:*:*:*:*:*+ 6 more
    • cpe:2.3:a:oracle:flexcube_private_banking:12.0.1:*:*:*:*:*:*:*
    • cpe:2.3:a:oracle:flexcube_private_banking:12.0.2:*:*:*:*:*:*:*
    • cpe:2.3:a:oracle:flexcube_private_banking:1.7:*:*:*:*:*:*:*
    • cpe:2.3:a:oracle:flexcube_private_banking:2.0:*:*:*:*:*:*:*
    • cpe:2.3:a:oracle:flexcube_private_banking:2.0.1:*:*:*:*:*:*:*
    • cpe:2.3:a:oracle:flexcube_private_banking:2.2.0.1:*:*:*:*:*:*:*
    • cpe:2.3:a:oracle:flexcube_private_banking:3.0:*:*:*:*:*:*:*
  • cpe:2.3:a:oracle:mysql_enterprise_monitor:*:*:*:*:*:*:*:*
    Range: <=2.3.14
  • cpe:2.3:a:oracle:webcenter_sites:11.1.1.6.1:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:a:oracle:webcenter_sites:11.1.1.6.1:*:*:*:*:*:*:*
    • cpe:2.3:a:oracle:webcenter_sites:11.1.1.8.0:*:*:*:*:*:*:*

Patches

2
c643336945dd

Merged from STRUTS_2_3_15_1_X - Disables DMI [from revision 1524296]

https://github.com/apache/strutsLukasz LenartSep 22, 2013via ghsa
9 files changed · +59 32
  • core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java+24 13 modified
    @@ -1,4 +1,5 @@
     /*
    + * $Id$
      * $Id$
      *
      * Licensed to the Apache Software Foundation (ASF) under one
    @@ -33,6 +34,7 @@
     import org.apache.struts2.RequestUtils;
     import org.apache.struts2.ServletActionContext;
     import org.apache.struts2.StrutsConstants;
    +import org.apache.struts2.dispatcher.ServletDispatcherResult;
     import org.apache.struts2.util.PrefixTrie;
     
     import javax.servlet.http.HttpServletRequest;
    @@ -168,8 +170,9 @@ public class DefaultActionMapper implements ActionMapper {
     
         protected static final String METHOD_PREFIX = "method:";
         protected static final String ACTION_PREFIX = "action:";
    +    private static final String STRUTS2_ACTION_PREFIX_PARSED = "_struts2_action_prefix_parsed";
     
    -    protected boolean allowDynamicMethodCalls = true;
    +    protected boolean allowDynamicMethodCalls = false;
         protected boolean allowSlashesInActionNames = false;
         protected boolean alwaysSelectFullNamespace = false;
         protected PrefixTrie prefixTrie = null;
    @@ -186,25 +189,33 @@ public DefaultActionMapper() {
             prefixTrie = new PrefixTrie() {
                 {
                     put(METHOD_PREFIX, new ParameterAction() {
    -                    public void execute(String key, ActionMapping mapping) {
    +                    public void execute(String key, ActionMapping mapping, HttpServletRequest request) {
                             if (allowDynamicMethodCalls) {
                                 mapping.setMethod(key.substring(METHOD_PREFIX.length()));
                             }
                         }
                     });
     
                     put(ACTION_PREFIX, new ParameterAction() {
    -                    public void execute(String key, ActionMapping mapping) {
    -                        String name = key.substring(ACTION_PREFIX.length());
    -                        if (allowDynamicMethodCalls) {
    -                            int bang = name.indexOf('!');
    -                            if (bang != -1) {
    -                                String method = name.substring(bang + 1);
    -                                mapping.setMethod(method);
    -                                name = name.substring(0, bang);
    +                    public void execute(final String key, ActionMapping mapping, HttpServletRequest request) {
    +                        if (request != null && request.getAttribute(STRUTS2_ACTION_PREFIX_PARSED) == null) {
    +                            request.setAttribute(STRUTS2_ACTION_PREFIX_PARSED, true);
    +                            String name = key.substring(ACTION_PREFIX.length());
    +                            if (allowDynamicMethodCalls) {
    +                                int bang = name.indexOf('!');
    +                                if (bang != -1) {
    +                                    String method = name.substring(bang + 1);
    +                                    mapping.setMethod(method);
    +                                    name = name.substring(0, bang);
    +                                }
    +                            }
    +                            String actionName = cleanupActionName(name);
    +                            mapping.setName(actionName);
    +                            if (getDefaultExtension() != null) {
    +                                actionName = actionName + "." + getDefaultExtension();
                                 }
    +                            mapping.setResult(new ServletDispatcherResult(actionName));
                             }
    -                        mapping.setName(cleanupActionName(name));
                         }
                     });
     
    @@ -225,7 +236,7 @@ protected void addParameterAction(String prefix, ParameterAction parameterAction
     
         @Inject(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION)
         public void setAllowDynamicMethodCalls(String allow) {
    -        allowDynamicMethodCalls = "true".equals(allow);
    +        allowDynamicMethodCalls = "true".equalsIgnoreCase(allow);
         }
     
         @Inject(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES)
    @@ -335,7 +346,7 @@ public void handleSpecialParameters(HttpServletRequest request, ActionMapping ma
                 if (!uniqueParameters.contains(key)) {
                     ParameterAction parameterAction = (ParameterAction) prefixTrie.get(key);
                     if (parameterAction != null) {
    -                    parameterAction.execute(key, mapping);
    +                    parameterAction.execute(key, mapping, request);
                         uniqueParameters.add(key);
                         break;
                     }
    
  • core/src/main/java/org/apache/struts2/dispatcher/mapper/ParameterAction.java+3 1 modified
    @@ -21,6 +21,8 @@
     
     package org.apache.struts2.dispatcher.mapper;
     
    +import javax.servlet.http.HttpServletRequest;
    +
     /**
      * Defines a parameter action prefix.  This is executed when the configured prefix key is matched in a parameter
      * name, allowing the implementation to manipulate the action mapping accordingly.  For example, if the "action:foo"
    @@ -30,5 +32,5 @@
      * @since 2.1.0
      */
     public interface ParameterAction {
    -    void execute(String key, ActionMapping mapping);
    +    void execute(String key, ActionMapping mapping, HttpServletRequest request);
     }
    
  • core/src/main/resources/org/apache/struts2/default.properties+1 1 modified
    @@ -105,7 +105,7 @@ struts.serve.static.browserCache=true
     ### like method:bar (but not action:foo).
     ### An alternative to implicit dynamic method invocation is to use wildcard
     ### mappings, such as <action name="*/*" method="{2}" class="actions.{1}">
    -struts.enable.DynamicMethodInvocation = true
    +struts.enable.DynamicMethodInvocation = false
     
     ### Set this to true if you wish to allow slashes in your action names.  If false,
     ### Actions names cannot have slashes, and will be accessible via any directory
    
  • core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java+9 5 modified
    @@ -1,4 +1,5 @@
     /*
    + * $Id$
      * $Id$
      *
      * Licensed to the Apache Software Foundation (ASF) under one
    @@ -33,6 +34,7 @@
     import org.apache.struts2.dispatcher.StrutsResultSupport;
     import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest;
     
    +import javax.servlet.http.HttpServletRequest;
     import java.util.Arrays;
     import java.util.HashMap;
     import java.util.Map;
    @@ -88,6 +90,7 @@ public void testGetMappingWithMethod() throws Exception {
             req.addExpectedGetAttributeName("javax.servlet.include.servlet_path");
     
             DefaultActionMapper mapper = new DefaultActionMapper();
    +        mapper.setAllowDynamicMethodCalls("true");
             ActionMapping mapping = mapper.getMapping(req, configManager);
     
             assertEquals("/my/namespace", mapping.getNamespace());
    @@ -212,6 +215,7 @@ public void testGetMappingWithUnknownNamespaceButFullNamespaceSelect() throws Ex
     
         public void testGetMappingWithActionName_methodAndName() throws Exception {
             DefaultActionMapper mapper = new DefaultActionMapper();
    +        mapper.setAllowDynamicMethodCalls("true");
             ActionMapping mapping = mapper.getMappingFromActionName("actionName!add");
             assertEquals("actionName", mapping.getName());
             assertEquals("add", mapping.getMethod());
    @@ -407,7 +411,7 @@ public void testActionPrefix() throws Exception {
             DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
             ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
     
    -        assertEquals(actionMapping.getName(), "myAction");
    +        assertEquals("myAction", actionMapping.getName());
         }
     
         public void testActionPrefix_fromImageButton() throws Exception {
    @@ -423,7 +427,7 @@ public void testActionPrefix_fromImageButton() throws Exception {
             DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
             ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
     
    -        assertEquals(actionMapping.getName(), "myAction");
    +        assertEquals("myAction", actionMapping.getName());
         }
     
         public void testActionPrefix_fromIEImageButton() throws Exception {
    @@ -438,7 +442,7 @@ public void testActionPrefix_fromIEImageButton() throws Exception {
             DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
             ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
     
    -        assertEquals(actionMapping.getName(), "myAction");
    +        assertEquals("myAction", actionMapping.getName());
         }
     
         public void testRedirectPrefix() throws Exception {
    @@ -529,13 +533,13 @@ public void testCustomActionPrefix() throws Exception {
             Map parameterMap = new HashMap();
             parameterMap.put("foo:myAction", "");
     
    -        StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
    +        final StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
             request.setParameterMap(parameterMap);
             request.setupGetServletPath("/someServletPath.action");
     
             DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
             defaultActionMapper.addParameterAction("foo", new ParameterAction() {
    -            public void execute(String key, ActionMapping mapping) {
    +            public void execute(String key, ActionMapping mapping, HttpServletRequest request) {
                     mapping.setName("myAction");
                 }
             });
    
  • core/src/test/java/org/apache/struts2/dispatcher/mapper/Restful2ActionMapperTest.java+1 0 modified
    @@ -92,6 +92,7 @@ public void testGetId() throws Exception {
     
         public void testGetEdit() throws Exception {
             mapper.setIdParameterName("id");
    +        mapper.setAllowDynamicMethodCalls("true");
             req.setupGetRequestURI("/my/namespace/foo/3!edit");
             req.setupGetServletPath("/my/namespace/foo/3!edit");
             req.setupGetAttribute(null);
    
  • core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java+12 11 modified
    @@ -21,24 +21,24 @@
     
     package org.apache.struts2.views.jsp;
     
    -import java.util.HashMap;
    -
    -import javax.servlet.jsp.JspException;
    -import javax.servlet.jsp.PageContext;
    -
    +import com.mockobjects.dynamic.Mock;
    +import com.opensymphony.xwork2.Action;
    +import com.opensymphony.xwork2.ActionContext;
    +import com.opensymphony.xwork2.ActionInvocation;
    +import com.opensymphony.xwork2.ActionProxy;
    +import com.opensymphony.xwork2.config.entities.ActionConfig;
     import org.apache.struts2.ServletActionContext;
     import org.apache.struts2.StrutsException;
     import org.apache.struts2.TestAction;
     import org.apache.struts2.TestActionTagResult;
     import org.apache.struts2.TestConfigurationProvider;
     import org.apache.struts2.components.ActionComponent;
    +import org.apache.struts2.dispatcher.mapper.ActionMapper;
    +import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
     
    -import com.mockobjects.dynamic.Mock;
    -import com.opensymphony.xwork2.Action;
    -import com.opensymphony.xwork2.ActionContext;
    -import com.opensymphony.xwork2.ActionInvocation;
    -import com.opensymphony.xwork2.ActionProxy;
    -import com.opensymphony.xwork2.config.entities.ActionConfig;
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.PageContext;
    +import java.util.HashMap;
     
     
     /**
    @@ -282,6 +282,7 @@ public void testActionMethodWithExecuteResult() throws Exception {
             tag.setNamespace("");
             tag.setName("testActionTagAction!input");
             tag.setExecuteResult(true);
    +        ((DefaultActionMapper)container.getInstance(ActionMapper.class)).setAllowDynamicMethodCalls("true");
     
             tag.doStartTag();
     
    
  • core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java+5 0 modified
    @@ -39,6 +39,8 @@
     import org.apache.struts2.TestConfigurationProvider;
     import org.apache.struts2.components.Form;
     import org.apache.struts2.dispatcher.Dispatcher;
    +import org.apache.struts2.dispatcher.mapper.ActionMapper;
    +import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
     import org.apache.struts2.views.jsp.AbstractUITagTest;
     import org.apache.struts2.views.jsp.ActionTag;
     import org.easymock.EasyMock;
    @@ -110,6 +112,9 @@ public void testFormWithActionAttributeContainingBothActionAndDMIMethod() throws
             tag.setEnctype("myEncType");
             tag.setTitle("mytitle");
             tag.setOnsubmit("submitMe()");
    +
    +        ((DefaultActionMapper)container.getInstance(ActionMapper.class)).setAllowDynamicMethodCalls("true");
    +
             tag.doStartTag();
             tag.doEndTag();
     
    
  • plugins/rest/src/main/java/org/apache/struts2/rest/RestActionMapper.java+1 1 modified
    @@ -108,7 +108,7 @@ public class RestActionMapper extends DefaultActionMapper {
         private String optionsMethodName = "options";
         private String postContinueMethodName = "createContinue";
         private String putContinueMethodName = "updateContinue";
    -    private boolean allowDynamicMethodCalls = true;    
    +    private boolean allowDynamicMethodCalls = false;
         
         public RestActionMapper() {
         }
    
  • plugins/rest/src/test/java/org/apache/struts2/rest/RestActionMapperTest.java+3 0 modified
    @@ -200,6 +200,7 @@ public void testShouldAllowExclamation() throws Exception {
             req.setServletPath("/animals/dog/fido!edit");
             req.setMethod("GET");
     
    +        mapper.setAllowDynamicMethodCalls("true");
             ActionMapping mapping = mapper.getMapping(req, configManager);
     
             assertEquals("/animals", mapping.getNamespace());
    @@ -303,6 +304,8 @@ public void testDynamicMethodInvocation() throws Exception {
             req.setServletPath("/animals/dog/23!edit");
             req.setMethod("GET");
     
    +        mapper.setAllowDynamicMethodCalls("true");
    +
             // when
             ActionMapping actionMapping = mapper.getMapping(req, configManager);
     
    
58947c3f85ae

Disables DMI

https://github.com/apache/strutsLukasz LenartSep 18, 2013via ghsa
9 files changed · +59 32
  • core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java+24 13 modified
    @@ -1,4 +1,5 @@
     /*
    + * $Id$
      * $Id$
      *
      * Licensed to the Apache Software Foundation (ASF) under one
    @@ -33,6 +34,7 @@
     import org.apache.struts2.RequestUtils;
     import org.apache.struts2.ServletActionContext;
     import org.apache.struts2.StrutsConstants;
    +import org.apache.struts2.dispatcher.ServletDispatcherResult;
     import org.apache.struts2.util.PrefixTrie;
     
     import javax.servlet.http.HttpServletRequest;
    @@ -168,8 +170,9 @@ public class DefaultActionMapper implements ActionMapper {
     
         protected static final String METHOD_PREFIX = "method:";
         protected static final String ACTION_PREFIX = "action:";
    +    private static final String STRUTS2_ACTION_PREFIX_PARSED = "_struts2_action_prefix_parsed";
     
    -    protected boolean allowDynamicMethodCalls = true;
    +    protected boolean allowDynamicMethodCalls = false;
         protected boolean allowSlashesInActionNames = false;
         protected boolean alwaysSelectFullNamespace = false;
         protected PrefixTrie prefixTrie = null;
    @@ -186,25 +189,33 @@ public DefaultActionMapper() {
             prefixTrie = new PrefixTrie() {
                 {
                     put(METHOD_PREFIX, new ParameterAction() {
    -                    public void execute(String key, ActionMapping mapping) {
    +                    public void execute(String key, ActionMapping mapping, HttpServletRequest request) {
                             if (allowDynamicMethodCalls) {
                                 mapping.setMethod(key.substring(METHOD_PREFIX.length()));
                             }
                         }
                     });
     
                     put(ACTION_PREFIX, new ParameterAction() {
    -                    public void execute(String key, ActionMapping mapping) {
    -                        String name = key.substring(ACTION_PREFIX.length());
    -                        if (allowDynamicMethodCalls) {
    -                            int bang = name.indexOf('!');
    -                            if (bang != -1) {
    -                                String method = name.substring(bang + 1);
    -                                mapping.setMethod(method);
    -                                name = name.substring(0, bang);
    +                    public void execute(final String key, ActionMapping mapping, HttpServletRequest request) {
    +                        if (request != null && request.getAttribute(STRUTS2_ACTION_PREFIX_PARSED) == null) {
    +                            request.setAttribute(STRUTS2_ACTION_PREFIX_PARSED, true);
    +                            String name = key.substring(ACTION_PREFIX.length());
    +                            if (allowDynamicMethodCalls) {
    +                                int bang = name.indexOf('!');
    +                                if (bang != -1) {
    +                                    String method = name.substring(bang + 1);
    +                                    mapping.setMethod(method);
    +                                    name = name.substring(0, bang);
    +                                }
    +                            }
    +                            String actionName = cleanupActionName(name);
    +                            mapping.setName(actionName);
    +                            if (getDefaultExtension() != null) {
    +                                actionName = actionName + "." + getDefaultExtension();
                                 }
    +                            mapping.setResult(new ServletDispatcherResult(actionName));
                             }
    -                        mapping.setName(cleanupActionName(name));
                         }
                     });
     
    @@ -225,7 +236,7 @@ protected void addParameterAction(String prefix, ParameterAction parameterAction
     
         @Inject(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION)
         public void setAllowDynamicMethodCalls(String allow) {
    -        allowDynamicMethodCalls = "true".equals(allow);
    +        allowDynamicMethodCalls = "true".equalsIgnoreCase(allow);
         }
     
         @Inject(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES)
    @@ -335,7 +346,7 @@ public void handleSpecialParameters(HttpServletRequest request, ActionMapping ma
                 if (!uniqueParameters.contains(key)) {
                     ParameterAction parameterAction = (ParameterAction) prefixTrie.get(key);
                     if (parameterAction != null) {
    -                    parameterAction.execute(key, mapping);
    +                    parameterAction.execute(key, mapping, request);
                         uniqueParameters.add(key);
                         break;
                     }
    
  • core/src/main/java/org/apache/struts2/dispatcher/mapper/ParameterAction.java+3 1 modified
    @@ -21,6 +21,8 @@
     
     package org.apache.struts2.dispatcher.mapper;
     
    +import javax.servlet.http.HttpServletRequest;
    +
     /**
      * Defines a parameter action prefix.  This is executed when the configured prefix key is matched in a parameter
      * name, allowing the implementation to manipulate the action mapping accordingly.  For example, if the "action:foo"
    @@ -30,5 +32,5 @@
      * @since 2.1.0
      */
     public interface ParameterAction {
    -    void execute(String key, ActionMapping mapping);
    +    void execute(String key, ActionMapping mapping, HttpServletRequest request);
     }
    
  • core/src/main/resources/org/apache/struts2/default.properties+1 1 modified
    @@ -105,7 +105,7 @@ struts.serve.static.browserCache=true
     ### like method:bar (but not action:foo).
     ### An alternative to implicit dynamic method invocation is to use wildcard
     ### mappings, such as <action name="*/*" method="{2}" class="actions.{1}">
    -struts.enable.DynamicMethodInvocation = true
    +struts.enable.DynamicMethodInvocation = false
     
     ### Set this to true if you wish to allow slashes in your action names.  If false,
     ### Actions names cannot have slashes, and will be accessible via any directory
    
  • core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java+9 5 modified
    @@ -1,4 +1,5 @@
     /*
    + * $Id$
      * $Id$
      *
      * Licensed to the Apache Software Foundation (ASF) under one
    @@ -33,6 +34,7 @@
     import org.apache.struts2.dispatcher.StrutsResultSupport;
     import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest;
     
    +import javax.servlet.http.HttpServletRequest;
     import java.util.Arrays;
     import java.util.HashMap;
     import java.util.Map;
    @@ -88,6 +90,7 @@ public void testGetMappingWithMethod() throws Exception {
             req.addExpectedGetAttributeName("javax.servlet.include.servlet_path");
     
             DefaultActionMapper mapper = new DefaultActionMapper();
    +        mapper.setAllowDynamicMethodCalls("true");
             ActionMapping mapping = mapper.getMapping(req, configManager);
     
             assertEquals("/my/namespace", mapping.getNamespace());
    @@ -212,6 +215,7 @@ public void testGetMappingWithUnknownNamespaceButFullNamespaceSelect() throws Ex
     
         public void testGetMappingWithActionName_methodAndName() throws Exception {
             DefaultActionMapper mapper = new DefaultActionMapper();
    +        mapper.setAllowDynamicMethodCalls("true");
             ActionMapping mapping = mapper.getMappingFromActionName("actionName!add");
             assertEquals("actionName", mapping.getName());
             assertEquals("add", mapping.getMethod());
    @@ -407,7 +411,7 @@ public void testActionPrefix() throws Exception {
             DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
             ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
     
    -        assertEquals(actionMapping.getName(), "myAction");
    +        assertEquals("myAction", actionMapping.getName());
         }
     
         public void testActionPrefix_fromImageButton() throws Exception {
    @@ -423,7 +427,7 @@ public void testActionPrefix_fromImageButton() throws Exception {
             DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
             ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
     
    -        assertEquals(actionMapping.getName(), "myAction");
    +        assertEquals("myAction", actionMapping.getName());
         }
     
         public void testActionPrefix_fromIEImageButton() throws Exception {
    @@ -438,7 +442,7 @@ public void testActionPrefix_fromIEImageButton() throws Exception {
             DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
             ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
     
    -        assertEquals(actionMapping.getName(), "myAction");
    +        assertEquals("myAction", actionMapping.getName());
         }
     
         public void testRedirectPrefix() throws Exception {
    @@ -529,13 +533,13 @@ public void testCustomActionPrefix() throws Exception {
             Map parameterMap = new HashMap();
             parameterMap.put("foo:myAction", "");
     
    -        StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
    +        final StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
             request.setParameterMap(parameterMap);
             request.setupGetServletPath("/someServletPath.action");
     
             DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
             defaultActionMapper.addParameterAction("foo", new ParameterAction() {
    -            public void execute(String key, ActionMapping mapping) {
    +            public void execute(String key, ActionMapping mapping, HttpServletRequest request) {
                     mapping.setName("myAction");
                 }
             });
    
  • core/src/test/java/org/apache/struts2/dispatcher/mapper/Restful2ActionMapperTest.java+1 0 modified
    @@ -92,6 +92,7 @@ public void testGetId() throws Exception {
     
         public void testGetEdit() throws Exception {
             mapper.setIdParameterName("id");
    +        mapper.setAllowDynamicMethodCalls("true");
             req.setupGetRequestURI("/my/namespace/foo/3!edit");
             req.setupGetServletPath("/my/namespace/foo/3!edit");
             req.setupGetAttribute(null);
    
  • core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java+12 11 modified
    @@ -21,24 +21,24 @@
     
     package org.apache.struts2.views.jsp;
     
    -import java.util.HashMap;
    -
    -import javax.servlet.jsp.JspException;
    -import javax.servlet.jsp.PageContext;
    -
    +import com.mockobjects.dynamic.Mock;
    +import com.opensymphony.xwork2.Action;
    +import com.opensymphony.xwork2.ActionContext;
    +import com.opensymphony.xwork2.ActionInvocation;
    +import com.opensymphony.xwork2.ActionProxy;
    +import com.opensymphony.xwork2.config.entities.ActionConfig;
     import org.apache.struts2.ServletActionContext;
     import org.apache.struts2.StrutsException;
     import org.apache.struts2.TestAction;
     import org.apache.struts2.TestActionTagResult;
     import org.apache.struts2.TestConfigurationProvider;
     import org.apache.struts2.components.ActionComponent;
    +import org.apache.struts2.dispatcher.mapper.ActionMapper;
    +import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
     
    -import com.mockobjects.dynamic.Mock;
    -import com.opensymphony.xwork2.Action;
    -import com.opensymphony.xwork2.ActionContext;
    -import com.opensymphony.xwork2.ActionInvocation;
    -import com.opensymphony.xwork2.ActionProxy;
    -import com.opensymphony.xwork2.config.entities.ActionConfig;
    +import javax.servlet.jsp.JspException;
    +import javax.servlet.jsp.PageContext;
    +import java.util.HashMap;
     
     
     /**
    @@ -282,6 +282,7 @@ public void testActionMethodWithExecuteResult() throws Exception {
             tag.setNamespace("");
             tag.setName("testActionTagAction!input");
             tag.setExecuteResult(true);
    +        ((DefaultActionMapper)container.getInstance(ActionMapper.class)).setAllowDynamicMethodCalls("true");
     
             tag.doStartTag();
     
    
  • core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java+5 0 modified
    @@ -39,6 +39,8 @@
     import org.apache.struts2.TestConfigurationProvider;
     import org.apache.struts2.components.Form;
     import org.apache.struts2.dispatcher.Dispatcher;
    +import org.apache.struts2.dispatcher.mapper.ActionMapper;
    +import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
     import org.apache.struts2.views.jsp.AbstractUITagTest;
     import org.apache.struts2.views.jsp.ActionTag;
     import org.easymock.EasyMock;
    @@ -110,6 +112,9 @@ public void testFormWithActionAttributeContainingBothActionAndDMIMethod() throws
             tag.setEnctype("myEncType");
             tag.setTitle("mytitle");
             tag.setOnsubmit("submitMe()");
    +
    +        ((DefaultActionMapper)container.getInstance(ActionMapper.class)).setAllowDynamicMethodCalls("true");
    +
             tag.doStartTag();
             tag.doEndTag();
     
    
  • plugins/rest/src/main/java/org/apache/struts2/rest/RestActionMapper.java+1 1 modified
    @@ -108,7 +108,7 @@ public class RestActionMapper extends DefaultActionMapper {
         private String optionsMethodName = "options";
         private String postContinueMethodName = "createContinue";
         private String putContinueMethodName = "updateContinue";
    -    private boolean allowDynamicMethodCalls = true;    
    +    private boolean allowDynamicMethodCalls = false;
         
         public RestActionMapper() {
         }
    
  • plugins/rest/src/test/java/org/apache/struts2/rest/RestActionMapperTest.java+3 0 modified
    @@ -200,6 +200,7 @@ public void testShouldAllowExclamation() throws Exception {
             req.setServletPath("/animals/dog/fido!edit");
             req.setMethod("GET");
     
    +        mapper.setAllowDynamicMethodCalls("true");
             ActionMapping mapping = mapper.getMapping(req, configManager);
     
             assertEquals("/animals", mapping.getNamespace());
    @@ -303,6 +304,8 @@ public void testDynamicMethodInvocation() throws Exception {
             req.setServletPath("/animals/dog/23!edit");
             req.setMethod("GET");
     
    +        mapper.setAllowDynamicMethodCalls("true");
    +
             // when
             ActionMapping actionMapping = mapper.getMapping(req, configManager);
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.