You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Jim Rudnicki <jd...@pacbell.net> on 2000/07/03 09:57:43 UTC
Patch suggestion for org.apache.tomcat.util.FileUtil.java
In v3.1, Context.getRealPath() did not work for subdirectories. The
workaround was to
use "dot" as in:
getContext().getRealPath( "./subdir/file.xhtml" )
which would retrieve for example:
c:/tomcat/webapps/context/./subdir/file.xhtml
On Windows, this was an effective workaround.
The new version, 3.2b1, breaks this. The failing occurs in a security check
in
org.apache.tomcat.util.FileUtil.java at around line 152. A comparison is
made with the canonical path, which for the above
example would be
c:/tomcat/webapps/context/subdir/file.xhtml
and subsequently fails
This is the section of code that determines that the above example is
unsafe:
try {
canPath=new File(realPath).getCanonicalPath();
} catch( IOException ex ) {
ex.printStackTrace();
return null;
}
// This absPath/canPath comparison plugs security holes...
// On Windows, makes "x.jsp.", "x.Jsp", and "x.jsp%20"
// return 404 instead of the JSP source
// On all platforms, makes sure we don't let ../'s through
// Unfortunately, on Unix, it prevents symlinks from working
// So, a check for File.separatorChar='\\' ..... It hopefully
// happens on flavors of Windows.
if (File.separatorChar == '\\') {
// On Windows check ignore case....
if (!realPath.equalsIgnoreCase(canPath)){
int ls=realPath.lastIndexOf('\\');
if ( (ls > 0) &&
!realPath.substring(0,ls).equalsIgnoreCase(canPath) )
return null;
}
}
I believe the following patch to the beginning of this method provide
correct behavior
without compomising the security check. It works for me on Win98/Sun
JDK1.1.8.
Don't see why it would introduce a problem elsewhere:
public static String safePath( String base, String path ) {
/* Convert to one separator type */
String normP=path;
if( path.indexOf('\\') >=0 ) {
normP= path.replace('\\', '/');
}
/* Remove inconsequential "current directory" part
from path. Without this, check will unfairly fail the
safety check below ( canonical==real )
Do this after all separators have been converted
above. */
if( normP.startsWith("./") ) {
normP = normP.substring(2);
}
// Hack for Jsp ( and other servlets ) that use rel. paths
if( ! normP.startsWith("/") ) {
normP="/"+ normP;
}
String realPath= base + normP;
'nite,
Jim