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;