Skip to content

Commit

Permalink
WW-4090 Itroduces actions names' whitelisting
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszlenart committed Jun 3, 2013
1 parent 113c470 commit 01e6b25
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
3 changes: 3 additions & 0 deletions core/src/main/java/org/apache/struts2/StrutsConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,7 @@ public final class StrutsConstants {

public static final String STRUTS_EXPRESSION_PARSER = "struts.expression.parser";

/** actions names' whitelist **/
public static final String STRUTS_ALLOWED_ACTION_NAMES = "struts.allowed.action.names";

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,7 @@
import org.apache.struts2.util.PrefixTrie;

import javax.servlet.http.HttpServletRequest;
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.*;

/**
* <!-- START SNIPPET: javadoc -->
Expand Down Expand Up @@ -171,6 +166,7 @@ public class DefaultActionMapper implements ActionMapper {
protected boolean allowSlashesInActionNames = false;
protected boolean alwaysSelectFullNamespace = false;
protected PrefixTrie prefixTrie = null;
protected String allowedActionNames = "[a-z]*[A-Z]*[0-9]*[.\\-_!/]*";

protected List<String> extensions = new ArrayList<String>() {{
add("action");
Expand Down Expand Up @@ -260,6 +256,11 @@ public void setAlwaysSelectFullNamespace(String val) {
this.alwaysSelectFullNamespace = "true".equals(val);
}

@Inject(value = StrutsConstants.STRUTS_ALLOWED_ACTION_NAMES, required = false)
public void setAllowedActionNames(String allowedActionNames) {
this.allowedActionNames = allowedActionNames;
}

@Inject
public void setContainer(Container container) {
this.container = container;
Expand Down Expand Up @@ -417,7 +418,25 @@ protected void parseNameAndNamespace(String uri, ActionMapping mapping, Configur
}

mapping.setNamespace(namespace);
mapping.setName(name);
mapping.setName(cleanupActionName(name));
}

/**
* Cleans up action name from suspicious characters
*
* @param rawActionName action name extracted from URI
* @return safe action name
*/
protected String cleanupActionName(final String rawActionName) {
if (rawActionName.matches(allowedActionNames)) {
return rawActionName;
} else {
String cleanActionName = rawActionName;
for(String chunk : rawActionName.split(allowedActionNames)) {
cleanActionName = cleanActionName.replace(chunk, "");
}
return cleanActionName;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -747,4 +747,23 @@ public void testSetExtension() throws Exception {

}

public void testAllowedActionNames() throws Exception {
DefaultActionMapper mapper = new DefaultActionMapper();

String actionName = "action";
assertEquals(actionName, mapper.cleanupActionName(actionName));

actionName = "${action}";
assertEquals("action", mapper.cleanupActionName(actionName));

actionName = "${${%{action}}}";
assertEquals("action", mapper.cleanupActionName(actionName));

actionName = "${#foo='action',#foo}";
assertEquals("fooactionfoo", mapper.cleanupActionName(actionName));

actionName = "test-action";
assertEquals("test-action", mapper.cleanupActionName(actionName));
}

}

0 comments on commit 01e6b25

Please sign in to comment.