Author: etnu
Date: Thu Apr  2 03:26:29 2009
New Revision: 761153

URL: http://svn.apache.org/viewvc?rev=761153&view=rev
Log:
Escape angle brackets to prevent IE content sniffing, primarily because it can 
potentially be used to bypass other security features. It might be sufficient 
to only escape leading angle brackets, but I escape both to be completely sure. 
Note that this will cause an increase in output size, particularly when HTML 
fragments are a part of a payload.


Modified:
    
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
    
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/JsonSerializerTest.java

Modified: 
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java?rev=761153&r1=761152&r2=761153&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
 (original)
+++ 
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
 Thu Apr  2 03:26:29 2009
@@ -18,11 +18,12 @@
  */
 package org.apache.shindig.common;
 
+import org.apache.shindig.common.util.DateUtil;
+
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
 import com.google.common.collect.MapMaker;
+import com.google.common.collect.Maps;
 
-import org.apache.shindig.common.util.DateUtil;
 import org.joda.time.DateTime;
 import org.json.JSONArray;
 import org.json.JSONObject;
@@ -162,7 +163,7 @@
       // String-like Primitives
       appendString(buf, value.toString());
     } else if(value instanceof Date) {
-      appendString(buf, DateUtil.formatIso8601Date((Date)value));  
+      appendString(buf, DateUtil.formatIso8601Date((Date)value));
     } else if (value instanceof JSONObject) {
       appendJsonObject(buf, (JSONObject) value);
     } else if (value instanceof JSONArray) {
@@ -347,10 +348,9 @@
       return;
     }
 
-    char previous, current = 0;
+    char current = 0;
     buf.append('"');
     for (int i = 0, j = string.length(); i < j; ++i) {
-      previous = current;
       current = string.charAt(i);
       switch (current) {
         case '\\':
@@ -358,11 +358,13 @@
           buf.append('\\');
           buf.append(current);
           break;
-        case '/':
-          if (previous == '<') {
-            buf.append('\\');
-          }
-          buf.append(current);
+        // We escape angle brackets in order to prevent content sniffing in 
user agents like IE.
+        // This content sniffing can potentially be used to bypass other 
security restrictions.
+        case '<':
+          buf.append("\\u003c");
+          break;
+        case '>':
+          buf.append("\\u003e");
           break;
         default:
           if (current < ' ' || (current >= '\u0080' && current < '\u00a0') ||

Modified: 
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/JsonSerializerTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/JsonSerializerTest.java?rev=761153&r1=761152&r2=761153&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/JsonSerializerTest.java
 (original)
+++ 
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/JsonSerializerTest.java
 Thu Apr  2 03:26:29 2009
@@ -176,6 +176,18 @@
     assertEquals("\"\\t\\r value \\\\\\foo\\b\uFFFF\uBCAD\\n\\u0083\"", 
builder.toString());
   }
 
+  @Test
+  public void escapeBrackets() throws Exception {
+    StringBuilder builder = new StringBuilder();
+    JsonSerializer.appendString(builder, "Hello<world>foo < bar");
+
+    assertEquals("Hello\\u003cworld\\u003efoo \\u003c bar", 
builder.toString());
+
+    // Quick sanity check to make sure that this converts back cleanly.
+    JSONObject obj = new JSONObject("{foo:\"" + builder.toString() + "\"}");
+    assertEquals("Hello<world>foo < bar", obj.get("foo"));
+  }
+
   private static String avg(long start, long end, long runs) {
     double delta = end - start;
     return String.format("%f5", delta / runs);


Reply via email to