craigmcc    00/11/30 18:11:23

  Modified:    catalina/src/share/org/apache/catalina/connector
                        HttpResponseBase.java ResponseBase.java
               catalina/src/share/org/apache/catalina/core
                        LocalStrings.properties StandardContextValve.java
  Log:
  Fix a potential security problem in Tomcat 4.0.
  
  The servlet specification prohibits servlet containers from serving
  "files" in the WEB-INF directory of a web application.  Tomcat 4.0
  currently enforces this restriction on static resources (like
  /WEB-INF/web.xml), but allowed access to JSP pages stored there
  (/WEB-INF/index.jsp).  This access is now longer allowed.
  
  Submitted by: David Aiken <[EMAIL PROTECTED]>
  
  Revision  Changes    Path
  1.18      +16 -11    
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/HttpResponseBase.java
  
  Index: HttpResponseBase.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/HttpResponseBase.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- HttpResponseBase.java     2000/11/21 00:00:39     1.17
  +++ HttpResponseBase.java     2000/12/01 02:11:20     1.18
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/HttpResponseBase.java,v
 1.17 2000/11/21 00:00:39 craigmcc Exp $
  - * $Revision: 1.17 $
  - * $Date: 2000/11/21 00:00:39 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/HttpResponseBase.java,v
 1.18 2000/12/01 02:11:20 craigmcc Exp $
  + * $Revision: 1.18 $
  + * $Date: 2000/12/01 02:11:20 $
    *
    * ====================================================================
    *
  @@ -96,7 +96,7 @@
    * methods need to be implemented.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.17 $ $Date: 2000/11/21 00:00:39 $
  + * @version $Revision: 1.18 $ $Date: 2000/12/01 02:11:20 $
    */
   
   public class HttpResponseBase
  @@ -482,17 +482,19 @@
            outputWriter.print(message);
        }
        outputWriter.print("\r\n");
  -        //   log(request.getRequest().getProtocol() + " " + status + " " + message);
  +        //        System.out.println("sendHeaders: " +
  +        //                           request.getRequest().getProtocol() +
  +        //                           " " + status + " " + message);
   
        // Send the content-length and content-type headers (if any)
        if (getContentType() != null) {
            outputWriter.print("Content-Type: " + getContentType() + "\r\n");
  -            //           log(" Content-Type: " + getContentType());
  +            //            System.out.println(" Content-Type: " + getContentType());
        }
  -     if (getContentLength() >= 0) {
  +     if (getContentLength() > 0) {
            outputWriter.print("Content-Length: " + getContentLength() +
                               "\r\n");
  -            //           log("  Content-Length: " + getContentLength());
  +            //            System.out.println(" Content-Length: " + 
getContentLength());
        }
   
        // Send all specified headers (if any)
  @@ -508,7 +510,7 @@
                    outputWriter.print(": ");
                    outputWriter.print(value);
                    outputWriter.print("\r\n");
  -                    //                    log(" " + name + ": " + value);
  +                    //                    System.out.println(" " + name + ": " + 
value);
                }
            }
        }
  @@ -543,14 +545,17 @@
                outputWriter.print(": ");
                outputWriter.print(CookieTools.getCookieHeaderValue(cookie));
                outputWriter.print("\r\n");
  -                //                log(" " + CookieTools.getCookieHeaderName(cookie) 
+ ": " +
  -                //                    CookieTools.getCookieHeaderValue(cookie));
  +                //                System.out.println(" " +
  +                //                                   
CookieTools.getCookieHeaderName(cookie) +
  +                //                                   ": " +
  +                //                                   
CookieTools.getCookieHeaderValue(cookie));
            }
        }
   
        // Send a terminating blank line to mark the end of the headers
        outputWriter.print("\r\n");
        outputWriter.flush();
  +        //        System.out.println("----------");
   
           // The response is now committed
           committed = true;
  
  
  
  1.7       +5 -4      
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/ResponseBase.java
  
  Index: ResponseBase.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/ResponseBase.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ResponseBase.java 2000/10/28 19:02:56     1.6
  +++ ResponseBase.java 2000/12/01 02:11:21     1.7
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/ResponseBase.java,v
 1.6 2000/10/28 19:02:56 craigmcc Exp $
  - * $Revision: 1.6 $
  - * $Date: 2000/10/28 19:02:56 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/ResponseBase.java,v
 1.7 2000/12/01 02:11:21 craigmcc Exp $
  + * $Revision: 1.7 $
  + * $Date: 2000/12/01 02:11:21 $
    *
    * ====================================================================
    *
  @@ -88,7 +88,7 @@
    * the connector-specific methods need to be implemented.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.6 $ $Date: 2000/10/28 19:02:56 $
  + * @version $Revision: 1.7 $ $Date: 2000/12/01 02:11:21 $
    */
   
   public abstract class ResponseBase
  @@ -380,6 +380,7 @@
        // flush the necessary headers
        if (this.stream == null) {
            ServletOutputStream sos = getOutputStream();
  +            sos.flush();
            sos.close();
            return;
        }
  
  
  
  1.20      +1 -0      
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/LocalStrings.properties,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- LocalStrings.properties   2000/11/25 00:57:24     1.19
  +++ LocalStrings.properties   2000/12/01 02:11:22     1.20
  @@ -43,6 +43,7 @@
   standardContext.managerLoad=Exception loading sessions from persistent storage
   standardContext.managerUnload=Exception unloading sessions to persistent storage
   standardContext.mappingError=MAPPING configuration error for relative URI {0}
  +standardContext.notFound=The requested resource ({0}) is not available.
   standardContext.notReloadable=Reloading is disabled on this Context
   standardContext.notStarted=Context has not yet been started
   standardContext.notWrapper=Child of a Context must be a Wrapper
  
  
  
  1.5       +65 -7     
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContextValve.java
  
  Index: StandardContextValve.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContextValve.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- StandardContextValve.java 2000/11/02 06:14:09     1.4
  +++ StandardContextValve.java 2000/12/01 02:11:22     1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContextValve.java,v
 1.4 2000/11/02 06:14:09 remm Exp $
  - * $Revision: 1.4 $
  - * $Date: 2000/11/02 06:14:09 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContextValve.java,v
 1.5 2000/12/01 02:11:22 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2000/12/01 02:11:22 $
    *
    * ====================================================================
    *
  @@ -66,6 +66,7 @@
   
   
   import java.io.IOException;
  +import java.io.PrintWriter;
   import javax.servlet.ServletException;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
  @@ -87,7 +88,7 @@
    * when processing HTTP requests.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.4 $ $Date: 2000/11/02 06:14:09 $
  + * @version $Revision: 1.5 $ $Date: 2000/12/01 02:11:22 $
    */
   
   final class StandardContextValve
  @@ -147,13 +148,31 @@
            return;     // NOTE - Not much else we can do generically
        }
   
  +        // Disallow any direct access to resources under WEB-INF or META-INF
  +        String contextPath =
  +            ((HttpServletRequest) request.getRequest()).getContextPath();
  +        String requestURI =
  +            ((HttpServletRequest) request.getRequest()).getRequestURI();
  +        String relativeURI =
  +            requestURI.substring(contextPath.length()).toUpperCase();
  +        if (relativeURI.equals("/META-INF") ||
  +            relativeURI.equals("/WEB-INF") ||
  +            relativeURI.startsWith("/META-INF/") ||
  +            relativeURI.startsWith("/WEB-INF/")) {
  +            notFound(requestURI, (HttpServletResponse) response.getResponse());
  +            try {
  +                response.finishResponse();
  +            } catch (IOException e) {
  +                ;
  +            }
  +            return;
  +        }
  +
        // Select the Wrapper to be used for this Request
        StandardContext context = (StandardContext) getContainer();
        Wrapper wrapper = (Wrapper) context.map(request, true);
        if (wrapper == null) {
  -         ((HttpServletResponse) response.getResponse()).sendError
  -             (HttpServletResponse.SC_NOT_FOUND,
  -              sm.getString("standardContext.notFound"));
  +            notFound(requestURI, (HttpServletResponse) response.getResponse());
               try {
                   response.finishResponse();
               } catch (IOException e) {
  @@ -179,6 +198,45 @@
           if (context.isUseNaming()) {
               // Unbind the thread to the context
               ContextBindings.unbindThread(context.getName(), context);
  +        }
  +
  +    }
  +
  +
  +    // -------------------------------------------------------- Private Methods
  +
  +
  +    /**
  +     * Report a "not found" error for the specified resource.  FIXME:  We
  +     * should really be using the error reporting settings for this web
  +     * application, but currently that code runs at the wrapper level rather
  +     * than the context level.
  +     *
  +     * @param requestURI The request URI for the requested resource
  +     * @param response The response we are creating
  +     */
  +    private void notFound(String requestURI, HttpServletResponse response) {
  +
  +        try {
  +            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
  +            // response.setMessage(requestURI);
  +            response.setContentType("text/html");
  +            PrintWriter writer = response.getWriter();
  +            writer.println("<html>");
  +            writer.println("<head>");
  +            writer.println("<title>Tomcat Error Report</title>");
  +            writer.println("<body bgcolor=\"white\">");
  +            writer.println("<br><br>");
  +            writer.println("<h1>HTTP Status 404 - " + requestURI + "</h1>");
  +            writer.println(sm.getString("standardContext.notFound",
  +                                        requestURI));
  +            writer.println("</body>");
  +            writer.println("</html>");
  +            writer.flush();
  +        } catch (IllegalStateException e) {
  +            ;
  +        } catch (IOException e) {
  +            ;
           }
   
       }
  
  
  

Reply via email to