Versions Compared

Key

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

...

Following is an implementation of an isInSecureDir() method. This method ensures that the supplied file and all directories above it are owned by either the user or the superuser, that each directory lacks write access for any other users, and that directories above the given file may not be deleted or renamed by any other users (except the superuser).

Code Block
bgColor#ccccff
/**
 * Indicates if file lives in a secure directory relative to the program's user
 * @param file Path to test
 * @return true if file's directory is secure
 */public static boolean isInSecureDir(Path file) {
  return isInSecureDir( file, null);
}

public static boolean isInSecureDir(Path file, UserPrincipal user) {
  return isInSecureDir( file, null, 5); // maximun number of nested symlinks
}

/**
 * Indicates if 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 to tolerate before aborting
 * @return true * @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="4d153019f72cc6b8-dcd85d8d-4b3f4e9d-ab5ca90b-466f591a5f6fc1157569a262"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#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="ebda95eeb339ca64-38e9e720-439b468e-a5c48f39-08ee548396e1621ec3afe9ac"><ac:plain-text-body><![CDATA[

[[CVE 2008

AA. Bibliography#CVE 08]]

[CVE-2008-5354

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5354]

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="982f3eacad1de9eb-fa5443fe-47394ca9-b40ab073-8d1adbb6469f6b374b5ca60b"><ac:plain-text-body><![CDATA[

[[Darwin 2004

AA. Bibliography#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="62e3cf0e56a1db6f-ea2817b9-415b4ab3-a3edb5b7-ad92e37dd7105223dd21b074"><ac:plain-text-body><![CDATA[

[[Garfinkel 1996

AA. Bibliography#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="06eb20ab5b4dcb5e-b5431a00-442145b6-8b30962f-b3dbd8345a42efd0427a8cc4"><ac:plain-text-body><![CDATA[

[[Howard 2002

AA. Bibliography#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="a4da79c358b3d6c4-be139fcc-4f414855-9664b991-7d6021c5864ad074deab9c3b"><ac:plain-text-body><![CDATA[

[[J2SE 2011

AA. Bibliography#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="568e8763935ab879-97cea76f-425e415c-ac918e6a-5dd10446f26cb96643dad026"><ac:plain-text-body><![CDATA[

[[Open Group 2004

AA. Bibliography#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="6366f85f20569aaf-9535ada0-4530413b-a50e96d6-efd6c82d2cdf80004d8ff230"><ac:plain-text-body><![CDATA[

[[SDN 2008

AA. Bibliography#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="d78ef61d677dfc19-e7599ac0-42a549f5-9d6eaabc-72287b0e6453d5fd725fb2b3"><ac:plain-text-body><![CDATA[

[[Secunia 2008

AA. Bibliography#Secunia 08]]

[Secunia Advisory 20132

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

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

...