VFS security issues for jbossweb
starksm64 Nov 29, 2006 3:31 PMRemy brought up the following issue when looking at using the vfs in jbossweb:
There is the usual issue that (among other problems) exposes JSP source (a request for foo.jsP will not match the *.jsp pattern, but the default servlet will find and serve a file named foo.jsp on the filesystem).
To check case sensitivity (on a filesystem), you have to compare the absolute path (which will return the absolute path using what you used - here, it would be /some/path/foo.jsP) with the canonical path (which will rebuild everything from the filesystem, so it would be /some/path/foo.jsp). No match means the filesystem abstraction will return null (= not found).
However, this check does not work when symlinking is used on Unix, so there's an override flag.
Example code from Tomcat:
protected File file(String name) { File file = new File(base, name); if (file.exists() && file.canRead()) { if (allowLinking) return file; // Check that this file belongs to our root path String canPath = null; try { canPath = file.getCanonicalPath(); } catch (IOException e) { } if (canPath == null) return null; // Check to see if going outside of the web application root if (!canPath.startsWith(absoluteBase)) { return null; } // Case sensitivity check if (caseSensitive) { String fileAbsPath = file.getAbsolutePath(); if (fileAbsPath.endsWith(".")) fileAbsPath = fileAbsPath + "/"; String absPath = normalize(fileAbsPath); if (canPath != null) canPath = normalize(canPath); if ((absoluteBase.length() < absPath.length()) && (absoluteBase.length() < canPath.length())) { absPath = absPath.substring(absoluteBase.length() + 1); if ((canPath == null) || (absPath == null)) return null; if (absPath.equals("")) absPath = "/"; canPath = canPath.substring(absoluteBase.length() + 1); if (canPath.equals("")) canPath = "/"; if (!canPath.equals(absPath)) return null; } } } else { return null; } return file; }
Note: The normalization thingie removes ".." and things like that. It is there because of possible usage through the request dispatcher.
Note2: These operations are expensive, but there's a cache (another dir context) on top of that dir context.