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