...
| Code Block | ||
|---|---|---|
| ||
public static boolean isInSecureDir(Path file) {
return isInSecureDir(file, null);
}
public static boolean isInSecureDir(Path file, UserPrincipal user) {
return isInSecureDir(file, user, 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 UserPrincipal 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;
}
|
...
Performing operations on files in shared directories can result in DoS attacks. If the program has elevated privileges, privilege escalation exploits are possible.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
FIO00-J | Medium | Unlikely | Medium | P4 | L3 |
Related Guidelines
FIO32-C. Do not perform operations on devices that are only appropriate for files | |
CWE-67, Improper Handling of Windows Device Names |
Android Implementation Details
On Android, the SD card ( /sdcard or /mnt/sdcard ) is shared among multiple applications, so sensitive files should not be stored on the SD card (see DRD00-J. Do not store sensitive information on external storage (SD card)).
Bibliography
[API 2014] | Class |
Section 11.5, "Creating a Transient File" | |
Section 5.6, "Device Files" | |
Chapter 11, "Canonical Representation Issues" | |
"The | |
| [JDK Bug 2015] | Bug JDK-4171239 |
...
...