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.

Best regards,
Konstantin Kolinko

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

Reply via email to