Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#ccccff
public static boolean isInSecureDir(Path file) {
  return isInSecureDir(file, null);
} 
public static boolean isInSecureDir(Path file, UserPrincipal user) {
   return isInSecureDir(file, null, 5);
}

/**
 * Indicates whether file lives in a secure directory relative
 * to the program's user
 * @param file Path to test
 * @param user User to test. If null, defaults to current user
 * @param symlinkDepth Number of symbolic links allowed
 * @return true if file's directory is secure
 */
public static boolean isInSecureDir(Path file, UserPrincipal user,
                                    int symlinkDepth) {
  if (!file.isAbsolute()) {
    file = file.toAbsolutePath();
  } if (symlinkDepth <=0) {
      // Too many levels of symbolic links
      return false;
    }

  // Get UserPincipal for specified user and superuser
  FileSystem fileSystem =
      Paths.get(file.getRoot().toString()).getFileSystem();
  UserPrincipalLookupService upls = 
      fileSystem.getUserPrincipalLookupService();
  UserPrincipal root = null;
  try {
    root = upls.lookupPrincipalByName("root");
    if (user == null) {
      user = upls.lookupPrincipalByName(System.getProperty("user.name"));
    }
    if (root == null || user == null) {
      return false;
    }
  } catch (IOException x) {
    return false;
  }

  // If any parent dirs (from root on down) are not secure,
  // dir is not secure
  for (int i = 1; i <= file.getNameCount(); i++) {
    Path partialPath = Paths.get(file.getRoot().toString(),
                                 file.subpath(0, i).toString());

    try {
      if (Files.isSymbolicLink(partialPath)) {
        if (!isInSecureDir(Files.readSymbolicLink(partialPath),)) {
                           user, symlinkDepth - 1)
          // Symbolic link, linked-to dir not secure
          return false;
        }
      } else {
        UserPrincipal owner = Files.getOwner(partialPath);
        if (!user.equals(owner) && !root.equals(owner)) {
          // dir owned by someone else, not secure
          return false;
        }
        PosixFileAttributes attr =
            Files.readAttributes(partialPath, PosixFileAttributes.class);
        Set<PosixFilePermission> perms = attr.permissions();
        if (perms.contains(PosixFilePermission.GROUP_WRITE) ||
            perms.contains(PosixFilePermission.OTHERS_WRITE)) {
          // someone else can write files, not secure
          return false;
        }
      }
    } catch (IOException x) {
      return false;
    }
  }

  return true;
}

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8faeb560e1403034-164d0771-41ef44b0-9f1cbd8c-379e8bf64b29f8d545a0a443"><ac:plain-text-body><![CDATA[

[[API 2006

AA. References#API 06]]

Class File, methods createTempFile, delete, deleteOnExit

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="420b5d9e23886aa7-2d2dc1b5-454c4056-b60aa1bb-d80ee6cab9364750dfd18c14"><ac:plain-text-body><![CDATA[

[[Darwin 2004

AA. References#Darwin 04]]

11.5, Creating a Transient File

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="d89f15b6c93f687a-4f9f7bda-4e2c428c-a580b995-0967028f871ad8134ccbd34a"><ac:plain-text-body><![CDATA[

[[Garfinkel 1996

AA. References#Garfinkel 96]]

Section 5.6, Device Files

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="12ea64363d8c62db-2345391e-4f344e91-89d9bf77-42249b2d4b47a8f4e9876a80"><ac:plain-text-body><![CDATA[

[[Howard 2002

AA. References#Howard 02]]

Chapter 11, Canonical Representation Issues

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="e95cc0a21c09712d-4fa0bf74-4c054e24-941fa5a5-416c1372e7ddb1c9f3291607"><ac:plain-text-body><![CDATA[

[[J2SE 2011

AA. References#J2SE 11]]

The try-with-resources Statement

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="c94553e40df46a32-5643e443-45434eb8-884eb51c-5d2b36921eb5f8556fa20b99"><ac:plain-text-body><![CDATA[

[[Open Group 2004

AA. References#Open Group 04]]

[open()

http://www.opengroup.org/onlinepubs/009695399/functions/open.html]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="2550aec2d1ca3cd6-bb7cf055-475f4205-95de92e9-b53cbc4eef7dbb08a53fd5fe"><ac:plain-text-body><![CDATA[

[[SDN 2008

AA. References#SDN 08]]

Bug IDs 4171239, 4405521, 4635827, 4631820

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="7a7eab9e27fac370-25ab361c-435a4eaf-bdad97ed-59ed5934ea3f01cdbf21b4b8"><ac:plain-text-body><![CDATA[

[[Secunia 2008

AA. References#Secunia 08]]

[Secunia Advisory 20132

http://secunia.com/advisories/20132/]

]]></ac:plain-text-body></ac:structured-macro>

...