Versions Compared

Key

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

...

File identification is less of an issue for applications that maintain their files in secure directories where they can be accessed only by the owner of the file and (possibly) by a system administrator (see FIO00-J. Do not operate on files in shared directories).

Noncompliant Code Example

In this noncompliant code example, the file identified by the string filename is opened, processed, closed, and then reopened for reading:

...

Because the binding between the file name and the underlying file object is reevaluated when the BufferedReader is created, this code cannot guarantee that the file opened for reading is the same file that was previously opened for writing. An attacker could replace the original file (for example, with a symbolic link) between the first call to close() and the subsequent creation of the BufferedReader.

Noncompliant Code Example (isSameFile())

In this noncompliant code example, the programmer attempts to ensure that the file opened for reading is the same as the file previously opened for writing by calling the method isSameFile():

...

That is, isSameFile() may simply check that the paths to the two files are the same and cannot detect if the file at that path had been replaced by a different file between the two open operations.

Compliant Solution (Multiple Attributes)

This compliant solution checks the creation and last-modified times of the files to increase the likelihood that the file opened for reading is the same file that was written:

...

Although this solution is reasonably secure, a determined attacker could create a symbolic link with the same creation and last-modified times as the original file. Also, a TOCTOU race condition occurs between the time the file's attributes are first read and the time the file is first opened. Likewise, a second TOCTOU condition occurs the second time the attributes are read and the file is reopened.

Compliant Solution (POSIX fileKey Attribute)

In environments that support the fileKey attribute, a more reliable approach is to check that the fileKey attributes of the two files are the same. The fileKey attribute is an object that "uniquely identifies the file" [API 2011], as shown in this compliant solution:

...

This solution is not perfect. Like the previous compliant solution, it has a TOCTOU race window between the time the file's attributes are first read and the time the file is first opened. A second TOCTOU condition occurs the second time the attributes are read and the file is reopened.

Compliant Solution (RandomAccessFile)

A better approach is to avoid reopening a file. The following compliant solution demonstrates use of a RandomAccessFile, which can be opened for both reading and writing. Because the file is never closed, the race condition cannot occur.

Code Block
bgColor#ccccff
public void randomAccess_cs(String filename) throws IOException{
  // Identify a file by its path
  RandomAccessFile file = new RandomAccessFile( filename, "rw");

  // Write to file...

  // Go back to beginning and read contents
  file.seek(0);
  try {
    while (true) {
      String s = file.readUTF();
      System.out.print(s);
    }
  } catch (EOFException x) {
    // Ignore, this breaks out of while loop
  }
  br.close();
}

Noncompliant Code Example (File Size)

This noncompliant code example tries to ensure that the file it opens contains exactly 1024 bytes:

...

This code is subject to a TOCTOU race condition between when the file size is learned and when the file is opened. If an attacker replaces a 1024-byte file with another file during this race window, they can cause this program to open any file, defeating the check.

Compliant Solution (File Size)

This compliant solution uses the FileChannel.size() method to obtain the file size. Because this method is applied to the file only after it has been opened, this solution eliminates the race window.

...

 Attackers frequently exploit file-related vulnerabilities to cause programs to access an unintended file. Proper file identification is necessary to prevent exploitation.

Bibliography

...