Revision: 1494
http://stripes.svn.sourceforge.net/stripes/?rev=1494&view=revAuthor: bengunter
Date: 2012-05-17 21:33:30 +0000 (Thu, 17 May 2012)
Log Message:
-----------
Fixed STS-841: Validation sometimes fails with indexed property notation. I have disabled the use of bracket notation for bean properties (e.g., bean[property][nestedProperty]). It opens up security issues with both binding and validation. To truly support it would require earlier evaluation of expressions, which is less efficient than the way it works now. It would also require tinkering with a bunch of code that works well right now. And finally, the use of bracket notation for bean properties is poorly (or not at all) supported on the server side when it comes to validation, localization, and other things that were implemented with dot notation in mind.
Modified Paths:
--------------
branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/Node.java
branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/PropertyExpression.java
branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/PropertyExpressionEvaluation.java
Modified: branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/Node.java
===================================================================
--- branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/Node.java 2012-05-17 18:16:41 UTC (rev 1493)
+++ branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/Node.java 2012-05-17 21:33:30 UTC (rev 1494)
@@ -26,13 +26,15 @@
public class Node {
private String stringValue;
private Object typedValue;
+ private boolean bracketed;
private Node next;
private Node previous;
/** Constructs a new node with the String value and typed value provided. */
- public Node(String value, Object typedValue) {
+ public Node(String value, Object typedValue, boolean bracketed) {
this.stringValue = value;
this.typedValue = typedValue;
+ this.bracketed = bracketed;
}
/**
@@ -56,6 +58,9 @@
*/
public Object getTypedValue() { return typedValue; }
+ /** True if the expression that generated this node was inside square brackets. */
+ public boolean isBracketed() { return bracketed; }
+
/** Gets the next node in the expression. Returns null if this is the terminal node. */
public Node getNext() { return next; }
Modified: branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/PropertyExpression.java
===================================================================
--- branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/PropertyExpression.java 2012-05-17 18:16:41 UTC (rev 1493)
+++ branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/PropertyExpression.java 2012-05-17 21:33:30 UTC (rev 1494)
@@ -127,8 +127,8 @@
}
else {
String value = builder.toString();
- addNode(value, value.length() == 1 ? value.charAt(0) : value);
- builder = new StringBuilder();
+ addNode(value, value.length() == 1 ? value.charAt(0) : value, inSquareBrackets);
+ builder.setLength(0);
}
}
else if (inSingleQuotedString) { builder.append(ch); }
@@ -144,27 +144,27 @@
}
else {
String value = builder.toString();
- addNode(value, value);
- builder = new StringBuilder();
+ addNode(value, value, inSquareBrackets);
+ builder.setLength(0);
}
}
else if (inDoubleQuotedString) { builder.append(ch); }
// Deal with square brackets
else if (!inSquareBrackets && ch == '[') {
if (builder.length() > 0) {
- addNode(builder.toString(), null);
- builder = new StringBuilder();
+ addNode(builder.toString(), null, inSquareBrackets);
+ builder.setLength(0);
}
inSquareBrackets = true;
}
else if (inSquareBrackets) {
// Using the nested IF allows us to consume periods in unquoted strings of digits
if (ch == ']') {
- inSquareBrackets = false;
if (builder.length() > 0) {
- addNode(builder.toString(), null);
- builder = new StringBuilder();
+ addNode(builder.toString(), null, inSquareBrackets);
+ builder.setLength(0);
}
+ inSquareBrackets = false;
}
else {
builder.append(ch);
@@ -176,7 +176,7 @@
// Ignore pseudo-zero-length nodes
}
else {
- addNode(builder.toString(), null);
+ addNode(builder.toString(), null, inSquareBrackets);
builder = new StringBuilder();
}
}
@@ -199,7 +199,7 @@
"Expression appears to terminate inside of square bracketed sub-expression.");
}
else if (builder.length() > 0) {
- addNode(builder.toString(), null);
+ addNode(builder.toString(), null, inSquareBrackets);
}
}
}
@@ -210,8 +210,9 @@
* @param nodeValue the String part of the expression that the node represents
* @param typedValue a strongly typed value for the nodeValue if one is indicated by
* the expression String, otherwise null to automatically determine
+ * @param bracketed True if {@code nodeValue} was inside square brackets.
*/
- private void addNode(String nodeValue, Object typedValue) {
+ private void addNode(String nodeValue, Object typedValue, boolean bracketed) {
// Determine the primitive/wrapper type of the node
if (typedValue != null) {
// skip ahead
@@ -239,7 +240,7 @@
typedValue = nodeValue;
}
- Node node = new Node(nodeValue, typedValue);
+ Node node = new Node(nodeValue, typedValue, bracketed);
// Attach the node at the appropriate point in the expression
if (this.root == null) {
Modified: branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/PropertyExpressionEvaluation.java
===================================================================
--- branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/PropertyExpressionEvaluation.java 2012-05-17 18:16:41 UTC (rev 1493)
+++ branches/1.5.x/stripes/src/net/sourceforge/stripes/util/bean/PropertyExpressionEvaluation.java 2012-05-17 21:33:30 UTC (rev 1494)
@@ -73,6 +73,7 @@
}
fillInTypeInformation();
+ validateTypeInformation();
}
/**
@@ -194,6 +195,22 @@
}
/**
+ * Ensures no violations exist in the expression in the context of this evaluation. Currently,
+ * this ensures that no attempt is made to access a bean property via a bracket expression. Such
+ * an expression could be used to circumvent validations that use dot notation for the same
+ * property. See <a href="
http://www.stripesframework.org/jira/browse/STS-841">STS-841</a> for
+ * more information.
+ */
+ protected void validateTypeInformation() {
+ for (NodeEvaluation n = getRootNode(); n != null; n = n.getNext()) {
+ if (n.getType() == NodeType.BeanProperty && n.getNode().isBracketed()) {
+ throw new EvaluationException("The expression \"" + getExpression().getSource()
+ + "\" illegally attempts to access a bean property using bracket notation");
+ }
+ }
+ }
+
+ /**
* Fetches the type of a property with the given name on the Class of the specified type.
* Uses the methods first to fetch the generic type if a PropertyDescriptor can be found,
* otherwise looks for a public field and returns its generic type.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats.
http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/_______________________________________________
Stripes-development mailing list
Stripes-development@...
https://lists.sourceforge.net/lists/listinfo/stripes-development