URIParsedResult now has isPossiblyMaliciousURI() to check for username in host, which...
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Thu, 21 Aug 2008 04:33:42 +0000 (04:33 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Thu, 21 Aug 2008 04:33:42 +0000 (04:33 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@570 59b500cc-1b3d-0410-9834-0bbf25fbcc57

CHANGES
core/src/com/google/zxing/client/result/URIParsedResult.java
core/src/com/google/zxing/client/result/URIResultParser.java
core/test/src/com/google/zxing/client/result/URIParsedResultTestCase.java [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 0d99f1b..43a5ca6 100644 (file)
--- a/CHANGES
+++ b/CHANGES
 1.0 (? September 2008)
   - All new RIM client from LifeMarks
   - Initial Data Matrix detector included
+  - New and much improved Android 0.9-SDK compatible Android client
+  - Better 1D detection, especially UPC-E, due to loosened quite zone checks
+  - URIParsedResult now tries to warn about malicious URIs
\ No newline at end of file
index 1e63140..00df5dc 100644 (file)
@@ -26,7 +26,7 @@ public final class URIParsedResult extends ParsedResult {
 
   public URIParsedResult(String uri, String title) {
     super(ParsedResultType.URI);
-    this.uri = uri;
+    this.uri = massageURI(uri);
     this.title = title;
   }
 
@@ -38,6 +38,35 @@ public final class URIParsedResult extends ParsedResult {
     return title;
   }
 
+  /**
+   * @return true if the URI contains suspicious patterns that may suggest it intends to
+   *  mislead the user about its true nature. At the moment this looks for the presence
+   *  of user/password syntax in the host/authority portion of a URI which may be used
+   *  in attempts to make the URI's host appear to be other than it is. Example:
+   *  http://yourbank.com@phisher.com  This URI connects to phisher.com but may appear
+   *  to connect to yourbank.com at first glance.
+   */
+  public boolean isPossiblyMaliciousURI() {
+    return containsUser();
+  }
+
+  private boolean containsUser() {
+    // This method is likely not 100% RFC compliant yet
+    int hostStart = uri.indexOf(':'); // we should always have scheme at this point
+    hostStart++;
+    // Skip slashes preceding host
+    int uriLength = uri.length();
+    while (hostStart < uriLength && uri.charAt(hostStart) == '/') {
+      hostStart++;
+    }
+    int hostEnd = uri.indexOf('/', hostStart);
+    if (hostEnd < 0) {
+      hostEnd = uriLength;
+    }
+    int at = uri.indexOf('@', hostStart);
+    return at >= hostStart && at < hostEnd;
+  }
+
   public String getDisplayResult() {
     StringBuffer result = new StringBuffer();
     maybeAppend(uri, result);
@@ -45,5 +74,21 @@ public final class URIParsedResult extends ParsedResult {
     return result.toString();
   }
 
+  /**
+   * Transforms a string that represents a URI into something more proper, by adding or canonicalizing
+   * the protocol.
+   */
+  private static String massageURI(String uri) {
+    int protocolEnd = uri.indexOf(':');
+    if (protocolEnd < 0) {
+      // No protocol, assume http
+      uri = "http://" + uri;
+    } else {
+      // Lowercase protocol to avoid problems
+      uri = uri.substring(0, protocolEnd).toLowerCase() + uri.substring(protocolEnd);
+    }
+    return uri;
+  }
+
 
 }
\ No newline at end of file
index 1f4b8f4..10805f6 100644 (file)
@@ -33,29 +33,11 @@ final class URIResultParser extends ResultParser {
     if (!isBasicallyValidURI(rawText)) {
       return null;
     }
-    String uri = massagePossibleURI(rawText);
-    return new URIParsedResult(uri, null);
-  }
-
-  /**
-   * Transforms a string that possibly represents a URI into something more proper, by adding or canonicalizing
-   * the protocol.
-   */
-  private static String massagePossibleURI(String uri) {
-    // Take off leading "URL:" if present
-    if (uri.startsWith("URL:")) {
-      uri = uri.substring(4);
-    }
-    int protocolEnd = uri.indexOf(':');
-    if (protocolEnd < 0) {
-      // No protocol, assume http
-      uri = "http://" + uri;
-    } else {
-      // Lowercase protocol to avoid problems
-      uri = uri.substring(0, protocolEnd).toLowerCase() + uri.substring(protocolEnd);
-      // TODO this logic isn't quite right for URIs like "example.org:443/foo"
+    // We specifically handle the odd "URL" scheme here for simplicity
+    if (rawText.startsWith("URL:")) {
+      rawText = rawText.substring(4);
     }
-    return uri;
+    return new URIParsedResult(rawText, null);
   }
 
   /**
diff --git a/core/test/src/com/google/zxing/client/result/URIParsedResultTestCase.java b/core/test/src/com/google/zxing/client/result/URIParsedResultTestCase.java
new file mode 100644 (file)
index 0000000..fe75bfc
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2007 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.result;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@link com.google.zxing.client.result.URIParsedResult}.
+ *
+ * @author srowen@google.com (Sean Owen)
+ */
+public final class URIParsedResultTestCase extends TestCase {
+
+  public void testIsPossiblyMalicious() {
+    doTestIsPossiblyMalicious("http://google.com", false);
+    doTestIsPossiblyMalicious("http://google.com@evil.com", true);
+    doTestIsPossiblyMalicious("http://google.com:@evil.com", true);
+    doTestIsPossiblyMalicious("google.com:@evil.com", true);
+    doTestIsPossiblyMalicious("https://google.com:443", false);
+    doTestIsPossiblyMalicious("http://google.com/foo@bar", false);    
+  }
+
+  private void doTestIsPossiblyMalicious(String uri, boolean expected) {
+    URIParsedResult result = new URIParsedResult(uri, null);
+    assertEquals(expected, result.isPossiblyMaliciousURI());
+  }
+
+}
\ No newline at end of file