mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
Fixed a security issue (see [1] for further details)
[1] https://cwiki.apache.org/confluence/display/WW/S2-009 git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/branches/STRUTS_2_3_X@1233422 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -55,7 +55,7 @@
|
||||
<distributionManagement>
|
||||
<site>
|
||||
<id>apache-site</id>
|
||||
<url>scp://people.apache.org/www/struts.apache.org/2.3.1.1/</url>
|
||||
<url>scp://people.apache.org/www/struts.apache.org/2.x/</url>
|
||||
</site>
|
||||
</distributionManagement>
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
<properties>
|
||||
<currentVersion>${project.version}</currentVersion>
|
||||
<struts2.springPlatformVersion>3.0.5.RELEASE</struts2.springPlatformVersion>
|
||||
<ognl.version>3.0.3</ognl.version>
|
||||
<ognl.version>3.0.4</ognl.version>
|
||||
<asm.version>3.3</asm.version>
|
||||
<tiles.version>2.0.6</tiles.version>
|
||||
</properties>
|
||||
|
||||
+2
-2
@@ -135,7 +135,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
static boolean devMode = false;
|
||||
|
||||
// Allowed names of parameters
|
||||
private String acceptedParamNames = "[a-zA-Z0-9\\.\\]\\[\\(\\)_']+";
|
||||
private String acceptedParamNames = "\\w+((\\.\\w+)|(\\[\\d+\\])|(\\(\\d+\\))|(\\['\\w+'\\])|(\\('\\w+'\\)))*";
|
||||
private Pattern acceptedPattern = Pattern.compile(acceptedParamNames);
|
||||
|
||||
private ValueStackFactory valueStackFactory;
|
||||
@@ -289,7 +289,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
String name = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
try {
|
||||
newStack.setValue(name, value);
|
||||
newStack.setParameter(name, value);
|
||||
} catch (RuntimeException e) {
|
||||
if (devMode) {
|
||||
String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{
|
||||
|
||||
@@ -206,7 +206,23 @@ public class OgnlUtil {
|
||||
* Ideally, this should be handled by OGNL directly.
|
||||
*/
|
||||
public void setValue(String name, Map<String, Object> context, Object root, Object value) throws OgnlException {
|
||||
Ognl.setValue(compile(name), context, root, value);
|
||||
setValue(name, context, root, value, true);
|
||||
}
|
||||
|
||||
protected void setValue(String name, Map<String, Object> context, Object root, Object value, boolean evalName) throws OgnlException {
|
||||
Object tree = compile(name);
|
||||
if (!evalName && isEvalExpression(tree, context)) {
|
||||
throw new OgnlException("Eval expression cannot be used as parameter name");
|
||||
}
|
||||
Ognl.setValue(tree, context, root, value);
|
||||
}
|
||||
|
||||
private boolean isEvalExpression(Object tree, Map<String, Object> context) throws OgnlException {
|
||||
if (tree instanceof SimpleNode) {
|
||||
SimpleNode node = (SimpleNode) tree;
|
||||
return node.isEvalChain((OgnlContext) context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object getValue(String name, Map<String, Object> context, Object root) throws OgnlException {
|
||||
@@ -245,7 +261,7 @@ public class OgnlUtil {
|
||||
public void copy(Object from, Object to, Map<String, Object> context, Collection<String> exclusions, Collection<String> inclusions) {
|
||||
if (from == null || to == null) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Attempting to copy from or to a null source. This is illegal and is bein skipped. This may be due to an error in an OGNL expression, action chaining, or some other event.");
|
||||
LOG.warn("Attempting to copy from or to a null source. This is illegal and is bein skipped. This may be due to an error in an OGNL expression, action chaining, or some other event.");
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -284,7 +300,7 @@ public class OgnlUtil {
|
||||
copy = false;
|
||||
}
|
||||
|
||||
if (copy == true) {
|
||||
if (copy) {
|
||||
PropertyDescriptor toPd = toPdHash.get(fromPd.getName());
|
||||
if ((toPd != null) && (toPd.getWriteMethod() != null)) {
|
||||
try {
|
||||
|
||||
@@ -144,6 +144,15 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.opensymphony.xwork2.util.ValueStack#setParameter(String, Object)
|
||||
*/
|
||||
public void setParameter(String expr, Object value) {
|
||||
setValue(expr, value, devMode, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* @see com.opensymphony.xwork2.util.ValueStack#setValue(java.lang.String, java.lang.Object)
|
||||
*/
|
||||
@@ -155,9 +164,13 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
* @see com.opensymphony.xwork2.util.ValueStack#setValue(java.lang.String, java.lang.Object, boolean)
|
||||
*/
|
||||
public void setValue(String expr, Object value, boolean throwExceptionOnFailure) {
|
||||
setValue(expr, value, throwExceptionOnFailure, true);
|
||||
}
|
||||
|
||||
private void setValue(String expr, Object value, boolean throwExceptionOnFailure, boolean evalExpression) {
|
||||
Map<String, Object> context = getContext();
|
||||
try {
|
||||
trySetValue(expr, value, throwExceptionOnFailure, context);
|
||||
trySetValue(expr, value, throwExceptionOnFailure, context, evalExpression);
|
||||
} catch (OgnlException e) {
|
||||
handleOgnlException(expr, value, throwExceptionOnFailure, e);
|
||||
} catch (RuntimeException re) { //XW-281
|
||||
@@ -167,10 +180,10 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
}
|
||||
}
|
||||
|
||||
private void trySetValue(String expr, Object value, boolean throwExceptionOnFailure, Map<String, Object> context) throws OgnlException {
|
||||
private void trySetValue(String expr, Object value, boolean throwExceptionOnFailure, Map<String, Object> context, boolean evalExpression) throws OgnlException {
|
||||
context.put(XWorkConverter.CONVERSION_PROPERTY_FULLNAME, expr);
|
||||
context.put(REPORT_ERRORS_ON_NO_PROP, (throwExceptionOnFailure) ? Boolean.TRUE : Boolean.FALSE);
|
||||
ognlUtil.setValue(expr, context, root, value);
|
||||
ognlUtil.setValue(expr, context, root, value, evalExpression);
|
||||
}
|
||||
|
||||
private void cleanUpContext(Map<String, Object> context) {
|
||||
|
||||
@@ -74,6 +74,14 @@ public interface ValueStack {
|
||||
*/
|
||||
public abstract void setValue(String expr, Object value);
|
||||
|
||||
/**
|
||||
* Attempts to set a property on a bean in the stack with the given expression using the default search order.
|
||||
* N.B.: unlike #setValue(String,Object) it doesn't allow eval expression.
|
||||
* @param expr the expression defining the path to the property to be set.
|
||||
* @param value the value to be set into the named property
|
||||
*/
|
||||
void setParameter(String expr, Object value);
|
||||
|
||||
/**
|
||||
* Attempts to set a property on a bean in the stack with the given expression using the default search order.
|
||||
*
|
||||
|
||||
@@ -50,6 +50,10 @@ public class StubValueStack implements ValueStack {
|
||||
ctx.put(expr, value);
|
||||
}
|
||||
|
||||
public void setParameter(String expr, Object value) {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
}
|
||||
|
||||
public void setValue(String expr, Object value, boolean throwExceptionOnFailure) {
|
||||
ctx.put(expr, value);
|
||||
}
|
||||
|
||||
+4
@@ -509,6 +509,10 @@ public class ParametersInterceptorTest extends XWorkTestCase {
|
||||
public void setValue(String expr, Object value) {
|
||||
actual.put(expr, value);
|
||||
}
|
||||
@Override
|
||||
public void setParameter(String expr, Object value) {
|
||||
actual.put(expr, value);
|
||||
}
|
||||
};
|
||||
container.inject(stack);
|
||||
return stack;
|
||||
|
||||
Reference in New Issue
Block a user