5 Replies Latest reply on Jun 10, 2008 9:38 AM by Scott Stark

    VFS security issues for jbossweb

    Scott Stark Master

      Remy 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.

        • 1. Re: VFS security issues for jbossweb
          Scott Stark Master

          So either we support identifying such path mismatches, or jbossweb will have to go outside of the vfs to the java.io.File apis.

          • 2. Re: VFS security issues for jbossweb
            Remy Maucherat Novice

            Maybe it is possible to add a case sensitive option to allow enabling those checks.

            • 3. Re: VFS security issues for jbossweb
              Scott Stark Master

              That is what I'm going to do. The VFSContext has support for options so I'm just looking to add the same check tomcat has based on the same options.

              • 4. Re: VFS security issues for jbossweb
                Marko Strukelj Master

                I looked into this issue, and I have a working solution (not yet commited).

                As Scott mentioned briefly - there is a problem determining the actual name of the file reliably across operating systems. On Windows where filesystem is not case sensitive canonical name is reliable. On Unix when there are no symbolic links canonical name is reliable as well. However, if symbolic links are present, canonical name will return the name of the file pointed to by the link - likely a different name than returned by parent.list() - name matching will fail and files and directories that do exist will appear to not exist.

                Windows NTFS also has support for directory links (junctions), but these are invisible to java and pose no problem.

                As far as I understand there is no need to turn on case sensitivity on unix platforms - so extra name checking in addition to File.exists() is redundant (even unreliable if symlinks are present).

                Also as I understand Tomcat integration code would be the only one to require this functionality, so it should be the one to turn on case sensitivity for specific VFS contexts only - by adding an option '?caseSensitive=true' to VFS context URL.

                Maybe there could be some system property set in run.bat, but not in run.sh, to help tomcat integration code decide whether to use VFS case sensitivity or not.

                I also added a system property (jboss.vfs.forceCaseSensitive=true) that can be used to force case sensitivity on all VFS filesystem contexts, although I don't see why anyone would need that.

                If everything sounds ok I'll commit, and then someone can try it with tomcat integration code.


                - marko

                • 5. Re: VFS security issues for jbossweb
                  Scott Stark Master

                  Sounds fine. The issue is testing it. I guess the test itself should determine if its being run on a case insensitive file system.