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="2d7233118479b2f2-cffa2065-469f46bb-81da90dc-1925d0aacd07fdbb6f37868d"><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="6c88947ef7d41102-f0bfe741-47b04cc5-ac988f32-e8b1981d6225ce42880ec833"><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="628c94acf7380610-b5252b7e-4ee744a9-8fcba2d7-db017a099cd1cc5307f6120d"><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="fa2281cf52708506-b2abd357-445644cb-83439c0b-b2aace90306e8e421a70fcdf"><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="50a4f9ee240c869c-f428fa35-4a7549f8-b672b1b6-1b6ca5573a61b5ef6eeaee17"><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="9dd224e75e886634-07ce2ef8-44c74924-baeeb84c-489365124759c0aa3c9e8645"><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="f0a106e133e8cf34-7caeffcd-4a604108-aee3b0f3-57ac378f6b942444fb586f83"><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="c756e7536263ce40-c08e7952-41b842ee-8c2499f5-257b22d1c8f6dbd3dc3fd536"><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>

...