Jason, Lars, all, I've been investigating the normalized URL, encoded special characters, etc. issues with Tomcat 3.2.3 and I think I have a solution that both maintains the required level of security and allows the kind of thing that Lars and Jason are looking for. I've attached a patch that I would appreciate reviewed by committers to make sure I'm not missing something. What I've done is changed the existing RequestUtil.URLDecode() to prevent the decoding of some additional characters. There was already code there to prevent '/' and '\0' and I added the other protected chars '\\', '.' and '%'. I then removed the draconian test to 404 any URL containing these special chars. If a URI contains encoded special characters from this list then these characters *remain encoded* in the resulting URI. For example /fu/ba+r --> /fu/ba r /fu%2fba+r --> /fu%2fba r I've tested this with all the 'bad' URLs that used to expose JSP source or avoid security constraints and everything works fine. Tomcat will still normalize all URIs as soon as they arrive in the container (sorry Jason). To avoid normalizing data passed in the pathinfo you will need to encode the path characters and then have your servlet URL decode the path info. For example, assuming /fubar/* is the prefix mapping, http://server/fubar/http:%2f%2fURLInPathInfo or http://server/fubar/http:%2f/URLInPathInfo will return path info that can be decoded URLDecoder.decode() into http://URLInPathInfo. Comments? Marc Saegesser > -----Original Message----- > From: Marc Saegesser [mailto:[EMAIL PROTECTED]] > Sent: Thursday, September 13, 2001 12:49 PM > To: [EMAIL PROTECTED] > Subject: RE: URI handling in tomcat 3.2.3 > > > Lars, > > I agree with you. These encoded characters should be allowed in URIs and > disallowing them is a hack. Like I said, I think the approach sucks. We > were faced with a very serious security problem that had to be addressed > very quickly and the decision was made that it was better to > forbid certain > 'odd' URIs in order to guarantee that resources that the specification > *requires* to be protected were indeed protected. We need to > look into how > to solve the security problems without forbidden valid URIs, but right now > I'm about the only one around paying much attention to the > tomcat_32 branch > so I don't know what kind of time frame wold be involved to get this > changed. I do know that the solution will not be trivial. > > I mentioned Apache httpd only to show that our approach to this problem is > in-line with that taken by other industry leading products. We should not > (and I think have not) blindly follow httpd (it does a few other > things that > disagree with). > > Patches or discussion on how to go about fixing this are > certainly welcome! > > > Marc Saegesser > > > -----Original Message----- > > From: Lars Oppermann [mailto:[EMAIL PROTECTED]] > > Sent: Thursday, September 13, 2001 9:23 AM > > To: [EMAIL PROTECTED] > > Subject: Re: URI handling in tomcat 3.2.3 > > > > > > Hi Marc, > > > > Thanks for you reply... > > > > Marc Saegesser wrote: > > > I agree that this URI handling sucks. I'm the one that > > > committed the change that made it happen and I still > > > think it sucks. However, allowing these encoded characters > > > opens some very large security problems. > > > > From what I understand, these security problems are all related to > > mapping URIs to filesystem paths. So how do you feel about doing this > > processing in the filesystem (default) servlet? > > > > > Also, even if TC 3.2.x allowed these characters, the resulting URL > > > wouldn't be portable because several other web servers impose the > > > same restrictions. > > > [400 with Apache 1.3.19] > > > > I think, if it is possible to do this in a better way while keeping up > > the protection there is no reason for copying the behaviour of httpd. > > However, if those security implications can not be handled in the file > > servlet like I mentioned before, I'd need to do some more thinking on > > this point. > > > > > If you need to pass this sort of data to a servlet (or CGI) the most > > > portable way is to simply use a query string. > > > > Yes, that sounds like a straight-forward solution. Unfortunatly the > > service that gets excuted here will access some document and return an > > html representation. This document contains relative references within > > the hierarchy represented by the 'wrapped' URI. for this to work with a > > browser, the request URI has to be used, because the client can not > > resolve relative references inside a query (why should it) > > > > I belive that there are many more use-cases where using URIs to > > represent hierachical names that do not map to files is desirable, > > espacialy in a servlet environment. > > In httpd, which's main work consists of serving file-system resources > > this might be viewed differently > > > > Cheers, > > Lars > > -- > > ---------------------------------------------------------------------- > > Lars Oppermann <[EMAIL PROTECTED]> Sun Microsystems > > Software Engineer - Sun ONE Webtop Sachsenfeld 4 > > Phone: +49 40 23646 959 D-20097 Hamburg > > Fax: +49 40 23646 550 http://www.sun.com/webtop
? URIPatch.txt ? util/URLUtil.java-save Index: core/ContextManager.java =================================================================== RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java,v retrieving revision 1.100.2.26 diff -u -r1.100.2.26 ContextManager.java --- core/ContextManager.java 2001/07/17 04:25:54 1.100.2.26 +++ core/ContextManager.java 2001/09/20 14:30:09 @@ -750,10 +750,6 @@ */ req.setRequestURI(URLUtil.normalizeURI(req.getRequestURI())); String ucURI = req.getRequestURI().toUpperCase(); - if(ucURI.indexOf("%25") >= 0 || ucURI.indexOf("%2E") >= 0 || - ucURI.indexOf("%2F") >= 0 || ucURI.indexOf("%5C") >=0){ - res.setStatus(404); - } internalService( req, res ); // clean up Index: util/RequestUtil.java =================================================================== RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/Attic/RequestUtil.java,v retrieving revision 1.14.2.6 diff -u -r1.14.2.6 RequestUtil.java --- util/RequestUtil.java 2001/08/12 23:26:57 1.14.2.6 +++ util/RequestUtil.java 2001/09/20 14:30:09 @@ -326,7 +326,7 @@ continue; } else if (metaChar == '%') { char c = (char) Integer.parseInt(str.substring(strPos + 1, strPos + 3), 16); - if(c == '/' || c == '\0') + if(c == '/' || c == '%' || c=='.' || c == '\\' || c == '\0') throw new IllegalArgumentException("URL contains encoded special chars."); dec.append(c);