As usual, the problem turned out to be deeper then I first expected.
Here's what happened. There was a bug in 3.2.1 that servlet paths and path
info weren't being decoded as required by the spec. This was fixed in
3.2.2.
It also turns out that there was bug in JDK1.2.2 that caused %HH escape
characters in file: URLs to not be decoded. I originally thought the bug
was in 1.3.0, but after re-reading the URL spec I accept that the bug was
really in 1.2.2. The bottom line is that the behavior of file URLs is
different on different versions of Java.
Context.getResource() constructs a file: URL by concatenating the context
root with the servlet path. On JDK1.3.0 systems, this now results in the
servlet path getting decoded twice: once in RequestUtil and once by URL.
Decoding URLs more than once causes all kinds of security problems.
So, given that file: URLs behave differently on different system, we have to
adjust the input to the URL constructor in Context.getResource() so that the
file names passed in on systems without the bug have been URL encoded so
that the URL can then decode them and get the correct file name.
So now the question becomes determining if the system has the file: URL bug.
I don't think you can just look at the version number because not every
vendor's 1.2.2 implementation may be broken and every vendor's 1.3.x
implementation may not be fixed. So it comes down to checking the behavior
of URL to see what flavor you have. I've tried all kinds of combinations of
toString(), toExternalForm(), sameFile(), etc. and so far the only reliable
method I have for determining which version of URL you have is to actually
use it to open an InputStream and see if it works. For example a simple
routine could try to open file:%2e (i.e. the current directory). If it gets
a FileNotFoundException then it assumes that it has a broken URL
implementation, if it doesn't get an exception then it assumes that the URL
implementation is correct. Context.getResource() can now check if the URL
implementation is broken or not and do the right thing.
This fixes the security hole, but opens up a new kind of attack. A
malicious user on a JDK1.2.2 server could create a file called %2e in
Tomcat's working directory. This would cause Tomcat to not find resources
that it legitimately should find. This better than exposing the entire
server to prying eyes, but it still doesn't feel right.
I'm going to commit the fix as I have it now so that others can review it
and maybe come up with a better approach. I'm now planning to release beta
3 Saturday morning (central US time).
> -----Original Message-----
> From: Marc Saegesser [mailto:[EMAIL PROTECTED]]
> Sent: Friday, April 06, 2001 11:29 AM
> To: [EMAIL PROTECTED]
> Subject: [STATUS] Tomcat 3.2.2
>
>
> I've got a fix for the URL double decode security problem in Tomcat 3.2.2.
> I'm going to release Tomcat 3.2.2 beta 3 tonight to make this fix publicly
> available. Because the only change in Beta 3 is the security
> fix, this beta
> cycle will only be one week long. If no other security issues are found,
> I'll call a vote for 3.2.2 final late next week.
>
>
>