Revision: 1494
          http://stripes.svn.sourceforge.net/stripes/?rev=1494&view=rev
Author:   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
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to