...
Wiki Markup |
---|
A recently identified bug in JRE and JDK version 6.0 and earlier permits an attacker who can predict the names of temporary files to write malicious JAR files via unknown vectors \[[CVE 2008|AA. Bibliography#CVE 08]\]. Failure to reclaim temporary resources can cause rapid disk space exhaustion due to unreclaimed files \[[Secunia Advisory 20132|http://secunia.com/advisories/20132/]\]. |
Noncompliant Code Example
This noncompliant code example hardcodes the name of a temporary file; consequently, the file's name is predictable. Even though there is a built-in check to detect whether a file still exists after its creation, a an attacker can exploit the TOCTOU condition by altering or deleting the file before it is read.
Code Block | ||
---|---|---|
| ||
class TempFile{
public static void main(String[] args) throws IOException{
File f = new File("tempnam.tmp");
FileOutputStream fop = new FileOutputStream(f);
String str = "Data";
if(f.exists()){
fop.write(str.getBytes());
} else {
System.out.println("This file does not exist");
}
}
}
|
Additionally, the output stream remains open after use, which violates guideline FIO06-J. Ensure all resources are properly closed when they are no longer needed. The program also fails to delete the file after use.
Exclusive Access
Wiki Markup |
---|
Exclusive access grants unrestricted file access to the locking process while denying access to all other processes, thus eliminating the potential for a race condition on the locked region. The {{java.nio.channels.FileLock}} class facilitates file locking. According to the Java API \[[API 2006|AA. Bibliography#API 06]\] documentation |
...
Wiki Markup |
---|
"Whether or not a lock actually prevents another program from accessing the content of the locked region is system-dependent and consequently unspecified" \[[API 2006|AA. Bibliography#API 06]\]. |
Microsoft Windows uses a file-locking mechanism called mandatory locking because every process attempting access to a locked file region is subject to the restriction.
Linux implements both mandatory locks and advisory locks. Advisory locks are not enforced by the operating system, which diminishes their value from a security perspective. Unfortunately, the mandatory file lock in Linux is generally impractical because:1.
- Mandatory locking is supported only on local file systems; it lacks support for network file systems (such as NFS or AFS).
...
- File systems must be explicitly mounted with support for mandatory locking; this support is disabled by default.
...
- Locking relies on the set-group-ID bit, however that bit can be disabled by another process (thereby defeating the lock).
Removal Before Termination
Removing temporary files when they are no longer required allows file names and other resources (such as secondary storage) to be recycled. Each program is responsible for ensuring that temporary files are removed during normal operation. There is no surefire method that can guarantee the removal of orphaned files in the case of abnormal termination, even in the presence of a finally
block, because the finally
block may fail to execute. For this reason, many systems employ temporary file cleaner utilities to sweep temporary directories and remove old files. Such utilities can be invoked manually by a system administrator or can be periodically invoked by a system daemon. However, these utilities are themselves vulnerable to file-based exploits and often require the use of shared directories.
Noncompliant Code Example (predictability)
This noncompliant code example hardcodes the name of a temporary file; consequently, the file's name is predictable. Even though there is a built-in check to detect whether a file still exists after its creation, this check creates a TOCTOU race condition that an attacker can exploit, by altering or deleting the file between the check and the read.
Code Block | ||
---|---|---|
| ||
class TempFile{ public static void main(String[] args) throws IOException{ File f = new File("tempnam.tmp"); FileOutputStream fop = new FileOutputStream(f); String str = "Data"; if (f.exists()) { fop.write(str.getBytes()); fop.close(); } else { System.out.println("This file does not exist"); } } } |
Noncompliant Code Example (createTempFile()
, deleteOnExit()
)
This noncompliant code example improves over the previous noncompliant code example by using the method File.createTempFile()
to generate a unique temporary filename based on two parameters, a prefix and an extension. This is the only method currently designed and provided for producing unique file names; unfortunately, the names produced can be easy to predict. Mitigate this vulnerability by using a good random number generator to produce the prefix.
...
Wiki Markup |
---|
To work around the file/stream termination issue, always attempt to terminate the resource normally before invoking {{deleteOnExit()}}. This should have been done using {{fop.close()}} in the noncompliant code example. Using {{File.io.delete()}} to immediately delete the file is good practice, when possible; this avoids improper JVM termination related issues. Moreover, although unreliable, {{System.gc()}} may be invoked to free up related resources. Sometimes, the resources to be deleted cannot be closed first; see, for example, \[[Bug ID: 4635827|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4635827]\]. There is no known workaround for this case. Consequently, temporary files must be created only in secure directories. |
...