remm        02/03/12 23:42:11

  Modified:    coyote/src/java/org/apache/coyote/tomcat4
                        CoyoteConnector.java CoyoteProcessor.java
  Log:
  - Add the URI normalization code from TC 4 used to protect against some URI
    encoding based attacks. This may be useless in the HEAD branch after
    the proposed URI decoding refactoring is done, so this code can be disabled.
    It defaults to doing the checks, as some versions in the Tomcat 4.0.x branch
    are very likely to need it.
  
  Revision  Changes    Path
  1.3       +32 -4     
jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteConnector.java
  
  Index: CoyoteConnector.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteConnector.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- CoyoteConnector.java      27 Feb 2002 08:24:08 -0000      1.2
  +++ CoyoteConnector.java      13 Mar 2002 07:42:11 -0000      1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteConnector.java,v
 1.2 2002/02/27 08:24:08 remm Exp $
  - * $Revision: 1.2 $
  - * $Date: 2002/02/27 08:24:08 $
  + * $Header: 
/home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteConnector.java,v
 1.3 2002/03/13 07:42:11 remm Exp $
  + * $Revision: 1.3 $
  + * $Date: 2002/03/13 07:42:11 $
    *
    * ====================================================================
    *
  @@ -103,7 +103,7 @@
    *
    * @author Craig R. McClanahan
    * @author Remy Maucherat
  - * @version $Revision: 1.2 $ $Date: 2002/02/27 08:24:08 $
  + * @version $Revision: 1.3 $ $Date: 2002/03/13 07:42:11 $
    */
   
   
  @@ -326,6 +326,12 @@
           "org.apache.coyote.http11.Http11Processor";
   
   
  +    /**
  +     * Use URI normalization.
  +     */
  +    private boolean useURINormalizationHack = true;
  +
  +
       // ------------------------------------------------------------- Properties
   
   
  @@ -820,6 +826,28 @@
       public void setTcpNoDelay(boolean tcpNoDelay) {
   
           this.tcpNoDelay = tcpNoDelay;
  +
  +    }
  +
  +
  +    /**
  +     * Return the value of the Uri normalization flag.
  +     */
  +    public boolean getUseURINormalizationHack() {
  +
  +        return (this.useURINormalizationHack);
  +
  +    }
  +
  +
  +    /**
  +     * Set the value of the Uri normalization flag.
  +     * 
  +     * @param useURINormalizationHack The new flag value
  +     */
  +    public void setUseURINormalizationHack(boolean useURINormalizationHack) {
  +
  +        this.useURINormalizationHack = useURINormalizationHack;
   
       }
   
  
  
  
  1.12      +102 -7    
jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteProcessor.java
  
  Index: CoyoteProcessor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteProcessor.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- CoyoteProcessor.java      9 Mar 2002 17:40:01 -0000       1.11
  +++ CoyoteProcessor.java      13 Mar 2002 07:42:11 -0000      1.12
  @@ -1,6 +1,6 @@
  -/* * $Header: 
/home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteProcessor.java,v
 1.11 2002/03/09 17:40:01 remm Exp $
  - * $Revision: 1.11 $
  - * $Date: 2002/03/09 17:40:01 $
  +/* * $Header: 
/home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteProcessor.java,v
 1.12 2002/03/13 07:42:11 remm Exp $
  + * $Revision: 1.12 $
  + * $Date: 2002/03/13 07:42:11 $
    *
    * ====================================================================
    *
  @@ -112,7 +112,7 @@
    *
    * @author Craig R. McClanahan
    * @author Remy Maucherat
  - * @version $Revision: 1.11 $ $Date: 2002/03/09 17:40:01 $
  + * @version $Revision: 1.12 $ $Date: 2002/03/13 07:42:11 $
    */
   
   final class CoyoteProcessor
  @@ -301,7 +301,7 @@
           try {
               // Parse and set Catalina and configuration specific 
               // request parameters
  -            postParseRequest(req);
  +            postParseRequest(req, res);
               // Calling the container
               connector.getContainer().invoke(request, response);
               response.finishResponse();
  @@ -370,7 +370,7 @@
       /**
        * Parse additional request parameters.
        */
  -    protected void postParseRequest(Request req)
  +    protected void postParseRequest(Request req, Response res)
           throws IOException {
   
           request.setSocket(socket);
  @@ -385,6 +385,17 @@
           else
               request.setServerPort(serverPort);
   
  +        // Normalize URI is needed for security reasons on older versions 
  +        // of Tomcat
  +        if (connector.getUseURINormalizationHack()) {
  +            String uri = normalize(request.getRequestURI());
  +            if (uri == null) {
  +                res.setStatus(400);
  +                res.setMessage("Invalid URI");
  +                throw new IOException("Invalid URI");
  +            }
  +        }
  +
           parseHost();
           parseSessionId();
           parseCookies();
  @@ -472,7 +483,7 @@
        * Parse cookies.
        * Note: Using Coyote native cookie parser to parse cookies would be faster
        * but a conversion to Catalina own cookies would then be needed, which 
  -     * would take away most if not all of theperformance benefit.
  +     * would take away most if not all of the performance benefit.
        */
       protected void parseCookies() {
   
  @@ -501,6 +512,90 @@
                   request.addCookie(cookies[i]);
               }
           }
  +
  +    }
  +
  +
  +    /**
  +     * Return a context-relative path, beginning with a "/", that represents
  +     * the canonical version of the specified path after ".." and "." elements
  +     * are resolved out.  If the specified path attempts to go outside the
  +     * boundaries of the current context (i.e. too many ".." path elements
  +     * are present), return <code>null</code> instead.
  +     *
  +     * @param path Path to be normalized
  +     */
  +    protected String normalize(String path) {
  +
  +        if (path == null)
  +            return null;
  +
  +        // Create a place for the normalized path
  +        String normalized = path;
  +
  +        // Normalize "/%7E" and "/%7e" at the beginning to "/~"
  +        if (normalized.startsWith("/%7E") ||
  +            normalized.startsWith("/%7e"))
  +            normalized = "/~" + normalized.substring(4);
  +
  +        // Prevent encoding '%', '/', '.' and '\', which are special reserved
  +        // characters
  +        if ((normalized.indexOf("%25") >= 0)
  +            || (normalized.indexOf("%2F") >= 0)
  +            || (normalized.indexOf("%2E") >= 0)
  +            || (normalized.indexOf("%5C") >= 0)
  +            || (normalized.indexOf("%2f") >= 0)
  +            || (normalized.indexOf("%2e") >= 0)
  +            || (normalized.indexOf("%5c") >= 0)) {
  +            return null;
  +        }
  +
  +        if (normalized.equals("/."))
  +            return "/";
  +
  +        // Normalize the slashes and add leading slash if necessary
  +        if (normalized.indexOf('\\') >= 0)
  +            normalized = normalized.replace('\\', '/');
  +        if (!normalized.startsWith("/"))
  +            normalized = "/" + normalized;
  +
  +        // Resolve occurrences of "//" in the normalized path
  +        while (true) {
  +            int index = normalized.indexOf("//");
  +            if (index < 0)
  +                break;
  +            normalized = normalized.substring(0, index) +
  +                normalized.substring(index + 1);
  +        }
  +
  +        // Resolve occurrences of "/./" in the normalized path
  +        while (true) {
  +            int index = normalized.indexOf("/./");
  +            if (index < 0)
  +                break;
  +            normalized = normalized.substring(0, index) +
  +                normalized.substring(index + 2);
  +        }
  +
  +        // Resolve occurrences of "/../" in the normalized path
  +        while (true) {
  +            int index = normalized.indexOf("/../");
  +            if (index < 0)
  +                break;
  +            if (index == 0)
  +                return (null);  // Trying to go outside our context
  +            int index2 = normalized.lastIndexOf('/', index - 1);
  +            normalized = normalized.substring(0, index2) +
  +                normalized.substring(index + 3);
  +        }
  +
  +        // Declare occurrences of "/..." (three or more dots) to be invalid
  +        // (on some Windows platforms this walks the directory tree!!!)
  +        if (normalized.indexOf("/...") >= 0)
  +            return (null);
  +
  +        // Return the normalized path that we have completed
  +        return (normalized);
   
       }
   
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to