VYPR
Critical severity9.8CISA KEVNVD Advisory· Published Jul 20, 2013· Updated Apr 22, 2026

CVE-2013-2251

CVE-2013-2251

Description

Apache Struts 2.0.0 through 2.3.15 allows remote attackers to execute arbitrary OGNL expressions via a parameter with a crafted (1) action:, (2) redirect:, or (3) redirectAction: prefix.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.struts:struts2-coreMaven
< 2.3.15.12.3.15.1

Affected products

9
  • Apache/Archiva3 versions
    cpe:2.3:a:apache:archiva:*:*:*:*:*:*:*:*+ 2 more
    • cpe:2.3:a:apache:archiva:*:*:*:*:*:*:*:*range: >=1.3,<1.3.8
    • cpe:2.3:a:apache:archiva:1.2:-:*:*:*:*:*:*
    • cpe:2.3:a:apache:archiva:1.2.2:*:*:*:*:*:*:*
  • cpe:2.3:a:apache:struts:*:*:*:*:*:*:*:*
    Range: >=2.0.0,<=2.3.15
  • cpe:2.3:a:fujitsu:interstage_business_process_manager_analytics:12.0:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:a:fujitsu:interstage_business_process_manager_analytics:12.0:*:*:*:*:*:*:*
    • cpe:2.3:a:fujitsu:interstage_business_process_manager_analytics:12.1:*:*:*:*:*:*:*
  • cpe:2.3:a:oracle:siebel_apps_-_e-billing:6.1:*:*:*:*:*:*:*+ 2 more
    • cpe:2.3:a:oracle:siebel_apps_-_e-billing:6.1:*:*:*:*:*:*:*
    • cpe:2.3:a:oracle:siebel_apps_-_e-billing:6.1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:oracle:siebel_apps_-_e-billing:6.2:*:*:*:*:*:*:*

Patches

2
630e1ba065a8

Merged from STRUTS_2_3_15_X

https://github.com/apache/strutsRené GielenJul 15, 2013via ghsa
3 files changed · +48 69
  • apps/showcase/src/main/webapp/tags/non-ui/actionPrefix/actionPrefixExample.ftl+3 7 modified
    @@ -37,17 +37,13 @@
     
     				<@s.textfield label="Enter Some Text" name="text" />
     
    -				<@s.submit name="action:actionPrefix" value="%{'action prefix'}" cssClass="btn" />
    +				<@s.submit action="actionPrefix" value="%{'action prefix'}" cssClass="btn" />
     
    -				<@s.submit name="method:alternateMethod" value="%{'method prefix'}" cssClass="btn" />
    -
    -				<@s.submit name="redirect:http://www.google.com" value="%{'redirect prefix'}" cssClass="btn" />
    -
    -				<@s.submit name="redirect-action:redirectActionPrefix" value="%{'redirect-action prefix'}" cssClass="btn" />
    +				<@s.submit method="alternateMethod" value="%{'method prefix'}" cssClass="btn" />
     
     				<@s.submit value="Normal Submit" cssClass="btn" />
     
    -	            <@s.submit name="action:redirectActionPrefixAction" value="%{'redirect-action without prefix'}" cssClass="btn" />
    +	            <@s.submit action="redirectActionPrefixAction" value="%{'redirectAction without prefix'}" cssClass="btn" />
     
     	        </@s.form>
     		</div>
    
  • core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java+8 31 modified
    @@ -33,11 +33,15 @@
     import org.apache.struts2.RequestUtils;
     import org.apache.struts2.ServletActionContext;
     import org.apache.struts2.StrutsConstants;
    -import org.apache.struts2.dispatcher.ServletRedirectResult;
     import org.apache.struts2.util.PrefixTrie;
     
     import javax.servlet.http.HttpServletRequest;
    -import java.util.*;
    +import java.util.ArrayList;
    +import java.util.Collections;
    +import java.util.HashSet;
    +import java.util.List;
    +import java.util.Map;
    +import java.util.Set;
     import java.util.regex.Pattern;
     
     /**
    @@ -164,8 +168,6 @@ public class DefaultActionMapper implements ActionMapper {
     
         protected static final String METHOD_PREFIX = "method:";
         protected static final String ACTION_PREFIX = "action:";
    -    protected static final String REDIRECT_PREFIX = "redirect:";
    -    protected static final String REDIRECT_ACTION_PREFIX = "redirectAction:";
     
         protected boolean allowDynamicMethodCalls = true;
         protected boolean allowSlashesInActionNames = false;
    @@ -186,8 +188,7 @@ public DefaultActionMapper() {
                     put(METHOD_PREFIX, new ParameterAction() {
                         public void execute(String key, ActionMapping mapping) {
                             if (allowDynamicMethodCalls) {
    -                            mapping.setMethod(key.substring(
    -                                    METHOD_PREFIX.length()));
    +                            mapping.setMethod(key.substring(METHOD_PREFIX.length()));
                             }
                         }
                     });
    @@ -203,34 +204,10 @@ public void execute(String key, ActionMapping mapping) {
                                     name = name.substring(0, bang);
                                 }
                             }
    -                        mapping.setName(name);
    +                        mapping.setName(cleanupActionName(name));
                         }
                     });
     
    -                put(REDIRECT_PREFIX, new ParameterAction() {
    -                    public void execute(String key, ActionMapping mapping) {
    -                        ServletRedirectResult redirect = new ServletRedirectResult();
    -                        container.inject(redirect);
    -                        redirect.setLocation(key.substring(REDIRECT_PREFIX
    -                                .length()));
    -                        mapping.setResult(redirect);
    -                    }
    -                });
    -
    -                put(REDIRECT_ACTION_PREFIX, new ParameterAction() {
    -                    public void execute(String key, ActionMapping mapping) {
    -                        String location = key.substring(REDIRECT_ACTION_PREFIX
    -                                .length());
    -                        ServletRedirectResult redirect = new ServletRedirectResult();
    -                        container.inject(redirect);
    -                        String extension = getDefaultExtension();
    -                        if (extension != null && extension.length() > 0) {
    -                            location += "." + extension;
    -                        }
    -                        redirect.setLocation(location);
    -                        mapping.setResult(redirect);
    -                    }
    -                });
                 }
             };
         }
    
  • core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java+37 31 modified
    @@ -21,21 +21,17 @@
     
     package org.apache.struts2.dispatcher.mapper;
     
    -import com.mockobjects.dynamic.Mock;
     import com.mockobjects.servlet.MockHttpServletRequest;
     import com.opensymphony.xwork2.ActionContext;
    -import com.opensymphony.xwork2.ActionInvocation;
     import com.opensymphony.xwork2.Result;
     import com.opensymphony.xwork2.config.Configuration;
     import com.opensymphony.xwork2.config.ConfigurationManager;
     import com.opensymphony.xwork2.config.entities.PackageConfig;
     import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
     import org.apache.struts2.ServletActionContext;
     import org.apache.struts2.StrutsTestCase;
    -import org.apache.struts2.dispatcher.ServletRedirectResult;
     import org.apache.struts2.dispatcher.StrutsResultSupport;
     import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest;
    -import org.apache.struts2.views.jsp.StrutsMockHttpServletResponse;
     
     import java.util.Arrays;
     import java.util.HashMap;
    @@ -447,7 +443,7 @@ public void testActionPrefix_fromIEImageButton() throws Exception {
     
         public void testRedirectPrefix() throws Exception {
             Map parameterMap = new HashMap();
    -        parameterMap.put(DefaultActionMapper.REDIRECT_PREFIX + "http://www.google.com", "");
    +        parameterMap.put("redirect:" + "http://www.google.com", "");
     
             StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
             request.setupGetServletPath("/someServletPath.action");
    @@ -458,25 +454,28 @@ public void testRedirectPrefix() throws Exception {
             ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
     
             Result result = actionMapping.getResult();
    -        assertNotNull(result);
    -        assertTrue(result instanceof ServletRedirectResult);
    -
    -        Mock invMock = new Mock(ActionInvocation.class);
    -        ActionInvocation inv = (ActionInvocation) invMock.proxy();
    -        ActionContext ctx = ActionContext.getContext();
    -        ctx.put(ServletActionContext.HTTP_REQUEST, request);
    -        StrutsMockHttpServletResponse response = new StrutsMockHttpServletResponse();
    -        ctx.put(ServletActionContext.HTTP_RESPONSE, response);
    -        invMock.expectAndReturn("getInvocationContext", ctx);
    -        invMock.expectAndReturn("getStack", ctx.getValueStack());
    -        result.execute(inv);
    -        assertEquals("http://www.google.com", response.getRedirectURL());
    -        //TODO: need to test location but there's noaccess to the property/method, unless we use reflection
    +        assertNull(result);
    +    }
    +
    +    public void testUnsafeRedirectPrefix() throws Exception {
    +        Map parameterMap = new HashMap();
    +        parameterMap.put("redirect:" + "http://%{3*4}", "");
    +
    +        StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
    +        request.setupGetServletPath("/someServletPath.action");
    +        request.setParameterMap(parameterMap);
    +
    +        DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
    +        defaultActionMapper.setContainer(container);
    +        ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
    +
    +        Result result = actionMapping.getResult();
    +        assertNull(result);
         }
     
         public void testRedirectActionPrefix() throws Exception {
             Map parameterMap = new HashMap();
    -        parameterMap.put(DefaultActionMapper.REDIRECT_ACTION_PREFIX + "myAction", "");
    +        parameterMap.put("redirectAction:" + "myAction", "");
     
             StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
             request.setupGetServletPath("/someServletPath.action");
    @@ -488,17 +487,29 @@ public void testRedirectActionPrefix() throws Exception {
     
     
             StrutsResultSupport result = (StrutsResultSupport) actionMapping.getResult();
    -        assertNotNull(result);
    -        assertTrue(result instanceof ServletRedirectResult);
    +        assertNull(result);
    +    }
     
    -        assertEquals("myAction.action", result.getLocation());
    +    public void testUnsafeRedirectActionPrefix() throws Exception {
    +        Map parameterMap = new HashMap();
    +        parameterMap.put("redirectAction:" + "%{3*4}", "");
     
    -        // TODO: need to test location but there's noaccess to the property/method, unless we use reflection
    +        StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
    +        request.setupGetServletPath("/someServletPath.action");
    +        request.setParameterMap(parameterMap);
    +
    +        DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
    +        defaultActionMapper.setContainer(container);
    +        ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
    +
    +
    +        StrutsResultSupport result = (StrutsResultSupport) actionMapping.getResult();
    +        assertNull(result);
         }
     
         public void testRedirectActionPrefixWithEmptyExtension() throws Exception {
             Map parameterMap = new HashMap();
    -        parameterMap.put(DefaultActionMapper.REDIRECT_ACTION_PREFIX + "myAction", "");
    +        parameterMap.put("redirectAction:" + "myAction", "");
     
             StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
             request.setupGetServletPath("/someServletPath");
    @@ -511,12 +522,7 @@ public void testRedirectActionPrefixWithEmptyExtension() throws Exception {
     
     
             StrutsResultSupport result = (StrutsResultSupport) actionMapping.getResult();
    -        assertNotNull(result);
    -        assertTrue(result instanceof ServletRedirectResult);
    -
    -        assertEquals("myAction", result.getLocation());
    -
    -        // TODO: need to test location but there's noaccess to the property/method, unless we use reflection
    +        assertNull(result);
         }
     
         public void testCustomActionPrefix() throws Exception {
    
3cfe34fefedc

WW-4140

https://github.com/apache/strutsRené GielenJul 14, 2013via ghsa
3 files changed · +48 69
  • apps/showcase/src/main/webapp/tags/non-ui/actionPrefix/actionPrefixExample.ftl+3 7 modified
    @@ -37,17 +37,13 @@
     
     				<@s.textfield label="Enter Some Text" name="text" />
     
    -				<@s.submit name="action:actionPrefix" value="%{'action prefix'}" cssClass="btn" />
    +				<@s.submit action="actionPrefix" value="%{'action prefix'}" cssClass="btn" />
     
    -				<@s.submit name="method:alternateMethod" value="%{'method prefix'}" cssClass="btn" />
    -
    -				<@s.submit name="redirect:http://www.google.com" value="%{'redirect prefix'}" cssClass="btn" />
    -
    -				<@s.submit name="redirect-action:redirectActionPrefix" value="%{'redirect-action prefix'}" cssClass="btn" />
    +				<@s.submit method="alternateMethod" value="%{'method prefix'}" cssClass="btn" />
     
     				<@s.submit value="Normal Submit" cssClass="btn" />
     
    -	            <@s.submit name="action:redirectActionPrefixAction" value="%{'redirect-action without prefix'}" cssClass="btn" />
    +	            <@s.submit action="redirectActionPrefixAction" value="%{'redirectAction without prefix'}" cssClass="btn" />
     
     	        </@s.form>
     		</div>
    
  • core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java+8 31 modified
    @@ -33,11 +33,15 @@
     import org.apache.struts2.RequestUtils;
     import org.apache.struts2.ServletActionContext;
     import org.apache.struts2.StrutsConstants;
    -import org.apache.struts2.dispatcher.ServletRedirectResult;
     import org.apache.struts2.util.PrefixTrie;
     
     import javax.servlet.http.HttpServletRequest;
    -import java.util.*;
    +import java.util.ArrayList;
    +import java.util.Collections;
    +import java.util.HashSet;
    +import java.util.List;
    +import java.util.Map;
    +import java.util.Set;
     import java.util.regex.Pattern;
     
     /**
    @@ -164,8 +168,6 @@ public class DefaultActionMapper implements ActionMapper {
     
         protected static final String METHOD_PREFIX = "method:";
         protected static final String ACTION_PREFIX = "action:";
    -    protected static final String REDIRECT_PREFIX = "redirect:";
    -    protected static final String REDIRECT_ACTION_PREFIX = "redirectAction:";
     
         protected boolean allowDynamicMethodCalls = true;
         protected boolean allowSlashesInActionNames = false;
    @@ -186,8 +188,7 @@ public DefaultActionMapper() {
                     put(METHOD_PREFIX, new ParameterAction() {
                         public void execute(String key, ActionMapping mapping) {
                             if (allowDynamicMethodCalls) {
    -                            mapping.setMethod(key.substring(
    -                                    METHOD_PREFIX.length()));
    +                            mapping.setMethod(key.substring(METHOD_PREFIX.length()));
                             }
                         }
                     });
    @@ -203,34 +204,10 @@ public void execute(String key, ActionMapping mapping) {
                                     name = name.substring(0, bang);
                                 }
                             }
    -                        mapping.setName(name);
    +                        mapping.setName(cleanupActionName(name));
                         }
                     });
     
    -                put(REDIRECT_PREFIX, new ParameterAction() {
    -                    public void execute(String key, ActionMapping mapping) {
    -                        ServletRedirectResult redirect = new ServletRedirectResult();
    -                        container.inject(redirect);
    -                        redirect.setLocation(key.substring(REDIRECT_PREFIX
    -                                .length()));
    -                        mapping.setResult(redirect);
    -                    }
    -                });
    -
    -                put(REDIRECT_ACTION_PREFIX, new ParameterAction() {
    -                    public void execute(String key, ActionMapping mapping) {
    -                        String location = key.substring(REDIRECT_ACTION_PREFIX
    -                                .length());
    -                        ServletRedirectResult redirect = new ServletRedirectResult();
    -                        container.inject(redirect);
    -                        String extension = getDefaultExtension();
    -                        if (extension != null && extension.length() > 0) {
    -                            location += "." + extension;
    -                        }
    -                        redirect.setLocation(location);
    -                        mapping.setResult(redirect);
    -                    }
    -                });
                 }
             };
         }
    
  • core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java+37 31 modified
    @@ -21,21 +21,17 @@
     
     package org.apache.struts2.dispatcher.mapper;
     
    -import com.mockobjects.dynamic.Mock;
     import com.mockobjects.servlet.MockHttpServletRequest;
     import com.opensymphony.xwork2.ActionContext;
    -import com.opensymphony.xwork2.ActionInvocation;
     import com.opensymphony.xwork2.Result;
     import com.opensymphony.xwork2.config.Configuration;
     import com.opensymphony.xwork2.config.ConfigurationManager;
     import com.opensymphony.xwork2.config.entities.PackageConfig;
     import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
     import org.apache.struts2.ServletActionContext;
     import org.apache.struts2.StrutsTestCase;
    -import org.apache.struts2.dispatcher.ServletRedirectResult;
     import org.apache.struts2.dispatcher.StrutsResultSupport;
     import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest;
    -import org.apache.struts2.views.jsp.StrutsMockHttpServletResponse;
     
     import java.util.Arrays;
     import java.util.HashMap;
    @@ -447,7 +443,7 @@ public void testActionPrefix_fromIEImageButton() throws Exception {
     
         public void testRedirectPrefix() throws Exception {
             Map parameterMap = new HashMap();
    -        parameterMap.put(DefaultActionMapper.REDIRECT_PREFIX + "http://www.google.com", "");
    +        parameterMap.put("redirect:" + "http://www.google.com", "");
     
             StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
             request.setupGetServletPath("/someServletPath.action");
    @@ -458,25 +454,28 @@ public void testRedirectPrefix() throws Exception {
             ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
     
             Result result = actionMapping.getResult();
    -        assertNotNull(result);
    -        assertTrue(result instanceof ServletRedirectResult);
    -
    -        Mock invMock = new Mock(ActionInvocation.class);
    -        ActionInvocation inv = (ActionInvocation) invMock.proxy();
    -        ActionContext ctx = ActionContext.getContext();
    -        ctx.put(ServletActionContext.HTTP_REQUEST, request);
    -        StrutsMockHttpServletResponse response = new StrutsMockHttpServletResponse();
    -        ctx.put(ServletActionContext.HTTP_RESPONSE, response);
    -        invMock.expectAndReturn("getInvocationContext", ctx);
    -        invMock.expectAndReturn("getStack", ctx.getValueStack());
    -        result.execute(inv);
    -        assertEquals("http://www.google.com", response.getRedirectURL());
    -        //TODO: need to test location but there's noaccess to the property/method, unless we use reflection
    +        assertNull(result);
    +    }
    +
    +    public void testUnsafeRedirectPrefix() throws Exception {
    +        Map parameterMap = new HashMap();
    +        parameterMap.put("redirect:" + "http://%{3*4}", "");
    +
    +        StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
    +        request.setupGetServletPath("/someServletPath.action");
    +        request.setParameterMap(parameterMap);
    +
    +        DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
    +        defaultActionMapper.setContainer(container);
    +        ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
    +
    +        Result result = actionMapping.getResult();
    +        assertNull(result);
         }
     
         public void testRedirectActionPrefix() throws Exception {
             Map parameterMap = new HashMap();
    -        parameterMap.put(DefaultActionMapper.REDIRECT_ACTION_PREFIX + "myAction", "");
    +        parameterMap.put("redirectAction:" + "myAction", "");
     
             StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
             request.setupGetServletPath("/someServletPath.action");
    @@ -488,17 +487,29 @@ public void testRedirectActionPrefix() throws Exception {
     
     
             StrutsResultSupport result = (StrutsResultSupport) actionMapping.getResult();
    -        assertNotNull(result);
    -        assertTrue(result instanceof ServletRedirectResult);
    +        assertNull(result);
    +    }
     
    -        assertEquals("myAction.action", result.getLocation());
    +    public void testUnsafeRedirectActionPrefix() throws Exception {
    +        Map parameterMap = new HashMap();
    +        parameterMap.put("redirectAction:" + "%{3*4}", "");
     
    -        // TODO: need to test location but there's noaccess to the property/method, unless we use reflection
    +        StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
    +        request.setupGetServletPath("/someServletPath.action");
    +        request.setParameterMap(parameterMap);
    +
    +        DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
    +        defaultActionMapper.setContainer(container);
    +        ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
    +
    +
    +        StrutsResultSupport result = (StrutsResultSupport) actionMapping.getResult();
    +        assertNull(result);
         }
     
         public void testRedirectActionPrefixWithEmptyExtension() throws Exception {
             Map parameterMap = new HashMap();
    -        parameterMap.put(DefaultActionMapper.REDIRECT_ACTION_PREFIX + "myAction", "");
    +        parameterMap.put("redirectAction:" + "myAction", "");
     
             StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
             request.setupGetServletPath("/someServletPath");
    @@ -511,12 +522,7 @@ public void testRedirectActionPrefixWithEmptyExtension() throws Exception {
     
     
             StrutsResultSupport result = (StrutsResultSupport) actionMapping.getResult();
    -        assertNotNull(result);
    -        assertTrue(result instanceof ServletRedirectResult);
    -
    -        assertEquals("myAction", result.getLocation());
    -
    -        // TODO: need to test location but there's noaccess to the property/method, unless we use reflection
    +        assertNull(result);
         }
     
         public void testCustomActionPrefix() throws Exception {
    

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

22

News mentions

0

No linked articles in our index yet.