Konstantin,

On 4/20/16 8:31 AM, Konstantin Kolinko wrote:
> 2016-04-19 22:42 GMT+03:00 Mark Thomas <ma...@apache.org>:
>> On 19/04/2016 19:38, Dimitar Valov wrote:
>>> All static resources such as index.html will not be found when application
>>> is added with <Context path="/" docBase="../../../"/>, for example tomcat
>>> is put inside the application's META-INF.
>>>
>>> I've drilled down that the AbstractFileResourceSet class is responsible for
>>> this behaviour, inside the protected final File file(String name, boolean
>>> mustExist) method. There absoluteBase and canonicalBase (absolute, unique
>>> with resolved symlinks) are used to determine if the file should be
>>> accessed based on a case sensitivity check.
>>>
>>> Everything works fine if the docBase is not just path like ../../.././../
>>> but has an actual directory at the end, like ../../../web-app. However in
>>> this edgy case the difference appears since the behaviour of
>>> the org.apache.tomcat.util.http.RequestUtil.normalize method has slightly
>>> different behavior than the File.getCanonicalPath.
>>>
>>> System.out.println(RequestUtil.normalize("/base/1/2/3/../../../"));
>>> /base/
>>>
>>> System.out.println(RequestUtil.normalize("/base/1/2/3/../../.."));
>>> /base/1/..
>>> System.out.println(new File("/base/1/2/3/../../../").getCanonicalPath());
>>> /base
>>>
>>> The added /from RequestUtil breakes the logic inside the file method, since
>>> when doing the substring operation inside AbstractFileResourceSet.file
>>> method it may or may not have a trailing /. In such situation <whatever
>>> path>/index.html substring with the absoluteBase becomes ndex.html. At the
>>> end the file method returns from here:
>>>
>>>         if (!canPath.equals(absPath)) // !"index.html".equals("ndex.html")
>>> => true
>>>                     return null;
>>>
>>> The RequestUtil comes from the http packages and follows their conventions
>>> when normalizing the path, so an obvious way to fix this is to add and if
>>> statement after the normalization
>>> inside AbstractFileResourceSet.initInternal.
>>>
>>>         this.absoluteBase = normalize(absolutePath);
>>>         if (this.absoluteBase.endsWith("/")) {
>>>         this.absoluteBase = this.absoluteBase.substring(0,
>>> this.absoluteBase.length() - 1);
>>>         }
>>>
>>> With Java 7 instead of using the RequestUtil for normalization, Path
>>> java.nio.file.Path.normalize() can accomplish the correct thing.
>>>
>>> Do you think that is something that can be fixed? Maybe the above is not
>>> the best approach, however it's the least invasive.
>>
>> We need to be very careful here since this is security sensitive.
>>
>> Given that normalize handles URIs, there is an argument for slightly
>> different handling of trailing '/'. I'm currently of the view (subject
>> to the results of some local tests I am running) that if the input ends
>> in '/', so should the output. If the input doesn't end in '/' neither
>> should the output unless the output is the string "/".
>>
>> The end result is likely to be that docBase values should not end in "/".
>>
> 
> (I have not looked at the context. Just a general comment / review of 
> r1740134)
> 
> There is a risk of normalizing Windows path of "C:\foo\.." into "C:"
> which denotes the current directory on drive C:  while the expected
> value is the root of the drive, "C:\".
> 
> I have not tested how  java.io.File("C:") actually works.

I don't have a Windows machine handy right this minute, but from my
previous experience, "C:" means "the current working directory on the C
drive, from this process's perspective.

For instance:

D:\> DIR C:\
...
Program Files
Windows
...

D:\> DIR C:
...
Program Files
Windows
...

D:\> CD C:\Windows
D:\> DIR C:
...
System
System32
...

So I would think that using "C:" (with no trailing path) from Java would
behave the same way: the current working directory *on that drive* would
be the one used.

I would expect it to work just like "." on *NIX.

-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to