Author: jfrederic.clere(a)jboss.com
Date: 2008-07-25 12:29:30 -0400 (Fri, 25 Jul 2008)
New Revision: 731
Modified:
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/connector/CoyoteAdapter.java
Log:
Add checkNormalize method to verify that the URI is still normalized after character
decoding.
Modified:
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/connector/CoyoteAdapter.java
===================================================================
---
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/connector/CoyoteAdapter.java 2008-07-25
16:26:00 UTC (rev 730)
+++
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/catalina/connector/CoyoteAdapter.java 2008-07-25
16:29:30 UTC (rev 731)
@@ -351,6 +351,12 @@
}
// Character decoding
convertURI(decodedURI, request);
+ // Check that the URI is still normalized
+ if (!checkNormalize(req.decodedURI())) {
+ res.setStatus(400);
+ res.setMessage("Invalid URI character encoding");
+ return false;
+ }
} else {
// The URL is chars or String, and has been sent using an in-memory
// protocol handler, we have to assume the URL has been properly
@@ -715,6 +721,67 @@
}
+ /**
+ * Check that the URI is normalized following character decoding.
+ * <p>
+ * This method checks for "\", "//", "/./" and
"/../". This method will
+ * return false if sequences that are supposed to be normalized still
+ * present in the URI.
+ *
+ * @param uriMB URI to be normalized
+ */
+ public static boolean checkNormalize(MessageBytes uriMB) {
+
+ CharChunk uriCC = uriMB.getCharChunk();
+ char[] c = uriCC.getChars();
+ int start = uriCC.getStart();
+ int end = uriCC.getEnd();
+
+ int pos = 0;
+
+ // Check for '\' and for null byte
+ for (pos = start; pos < end; pos++) {
+ if (c[pos] == '\\') {
+ return false;
+ }
+ if (c[pos] == 0) {
+ return false;
+ }
+ }
+
+ // Check for "//"
+ for (pos = start; pos < (end - 1); pos++) {
+ if (c[pos] == '/') {
+ if (c[pos + 1] == '/') {
+ return false;
+ }
+ }
+ }
+
+ // Check for URI ending with "/." or "/.."
+ if (((end - start) >= 2) && (c[end - 1] == '.')) {
+ if ((c[end - 2] == '/')
+ || ((c[end - 2] == '.')
+ && (c[end - 3] == '/'))) {
+ return false;
+ }
+ }
+
+ // Check for "/./"
+ if (uriCC.indexOf("/./", 0, 3, 0) >= 0) {
+ return false;
+ }
+
+ // Check for "/./"
+ if (uriCC.indexOf("/../", 0, 4, 0) >= 0) {
+ return false;
+ }
+
+ return true;
+
+ }
+
+
// ------------------------------------------------------ Protected Methods
Show replies by date