larryi      01/07/18 14:18:07

  Modified:    src/share/org/apache/tomcat/modules/mappers
                        DecodeInterceptor.java
  Log:
  Updated to implement rejection of unsafe escapes, i.e. %25, %2E, %2F, and
  %5C which are '%','.','/', and '\' respectively.  Note that the escape checking
  does not occur in the session id that follows ";jsessionid=" if found to be
  present. This behavior is optional and is controled by the "safe" property,
  which defaults to true.
  
  Normalization has been moved so that it occurs prior to decoding.  This
  means that getRequestURI() will return a normalized URI that remains
  encoded as required by the spec.  There is support for this normalization
  in RFC1630 (thanks Danny).  The normalization is also optional and
  is controlled by the "normalize" property, which defaults to true.
  
  The above rejection and normalization behavior is consistent with what
  has been implemented in Tomcat 4.0 and 3.2.3.
  
  Revision  Changes    Path
  1.6       +58 -14    
jakarta-tomcat/src/share/org/apache/tomcat/modules/mappers/DecodeInterceptor.java
  
  Index: DecodeInterceptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/mappers/DecodeInterceptor.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- DecodeInterceptor.java    2001/07/17 01:59:43     1.5
  +++ DecodeInterceptor.java    2001/07/18 21:18:07     1.6
  @@ -67,7 +67,9 @@
   
   /**
    * Default actions after receiving the request: get charset, unescape,
  - * pre-process.
  + * pre-process.  This intercept can optionally normalize the request
  + * and check for certain unsafe escapes.  Both of these options
  + * are on by default.
    * 
    */
   public class DecodeInterceptor extends  BaseInterceptor  {
  @@ -81,6 +83,7 @@
       private int encodingInfoNote;
       private int sessionEncodingNote;
   
  +    private boolean normalize=true;
       private boolean safe=true;
       
       public DecodeInterceptor() {
  @@ -105,10 +108,21 @@
        charsetURIAttribute=";" + charsetAttribute + "=";
       }
   
  -    /** Decode interceptor can normalize unsafe urls, by eliminating
  -     dangerous things like /../, // , etc - all of them are known
  -     as very dangerous for security.
  +    /** Decode interceptor can normalize urls, per RFC 1630
       */
  +    public void setNormalize( boolean b ) {
  +     normalize=b;
  +    }
  +
  +    /** Decode interceptor can reject unsafe urls. These are
  +        URL's containing the following escapes:
  +        %25 = '%'
  +        %2E = '.'
  +        %2F = '/'
  +        %5C = '\'
  +        These are rejected because they interfere with URL's
  +        pattern matching with reguard to security issues.
  +    */
       public void setSafe( boolean b ) {
        safe=b;
       }
  @@ -241,6 +255,32 @@
        }
        
       }
  +
  +    private boolean isSafeURI(MessageBytes pathMB) {
  +        int start = pathMB.indexOf("%");
  +        if( start >= 0 ) {
  +            int end = pathMB.indexOf(";jsessionid=");
  +            if( end < 0 || start < end ) {
  +                int percent = pathMB.indexOfIgnoreCase("%25",start);
  +                if( percent >= 0 && ( end < 0 || percent < end ) )
  +                    return false;
  +
  +                int period = pathMB.indexOfIgnoreCase("%2E",start);
  +                if( period >= 0 && ( end < 0 || period < end ) )
  +                    return false;
  +
  +                int fslash = pathMB.indexOfIgnoreCase("%2F",start);
  +                if( fslash >= 0 && ( end < 0 || fslash < end ) )
  +                    return false;
  +
  +                int bslash = pathMB.indexOfIgnoreCase("%5C",start);
  +                if( bslash >= 0 && ( end < 0 || bslash < end ) )
  +                    return false;
  +            }
  +        }
  +
  +        return true;
  +    }
       
       public int postReadRequest( Request req ) {
        MessageBytes pathMB = req.requestURI();
  @@ -251,7 +291,21 @@
   
        //if( path.indexOf("?") >=0 )
        //   throw new RuntimeException("ASSERT: ? in requestURI");
  +
  +        // If path is unsafe, return forbidden
  +        if( safe && !isSafeURI(pathMB) )
  +            return 403;
        
  +     if( normalize &&
  +         ( pathMB.indexOf("//") >= 0 ||
  +           pathMB.indexOf("/." ) >=0
  +           )) {
  +         //debug=1;
  +         normalizePath( pathMB );
  +         if( debug > 0 )
  +             log( "Normalized url "  + pathMB );
  +     }
  +
        // Set the char encoding first
        String charEncoding=null;       
        MimeHeaders headers=req.getMimeHeaders();
  @@ -331,16 +385,6 @@
                log( "Error decoding request ", ex);
                return 400;
            }
  -     }
  -
  -     if( safe &&
  -         ( pathMB.indexOf("//") >= 0 ||
  -           pathMB.indexOf("/." ) >=0
  -           )) {
  -         //debug=1;
  -         normalizePath( pathMB );
  -         if( debug > 0 )
  -             log( "Normalized url "  + pathMB );
        }
   
        return 0;
  
  
  

Reply via email to