You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Although creating a file is generally accomplished with a single method call, it actually has several issues to consider. What should be done if the file cannot be created? What should be done if the file already exists? What should be the file's initial attributes, such as permissions? Java provides several generations of file handling facilities. The original input/output facilities, which included basic file handling, are in the package java.io. More comprehensive facilities were included in JDK 1.4 with the so called "New I/O" package java.nio (see [Oracle 2010b]). This package introduced a number of methods to handle fine-grained control of file creation.

Noncompliant Code Example

This noncompliant code example tries to open a file for writing:

String filename = // Name of file to write
OutputStream out = new FileOutputStream(filename);
// Work with FILE

If the file existed before being opened, its former contents will be overwritten with the contents provided by the program.

Noncompliant Code Example (Append)

This noncompliant code example tries to avoid overwriting an existing file:

String filename = // Name of file to write
OutputStream out = new FileOutputStream(filename, true);
// Work with FILE

If the file existed before being opened, its new contents will be appended to the former contents. This code is compliant only if this was the intention of the programmer.

Noncompliant Code Example (TOCTOU)

This noncompliant code example tries to avoid altering an existing file by creating an empty file using java.io.File.createNewfile(). If a file with the given name already exists, then createNewFile() will return false.

OutputStream out = new FileOutputStream(filename, true);
if (!new File(filename).createNewFile()) {
    // File cannot be created...handle error
} else {
    OutputStream out = new FileOutputStream(filename);
    // Work with FILE
}

Unfortunately, this solution is subject to a TOCTOU (time-of-check-time-of-use) race condition. It is possible for an attacker to modify the file system such that the file that is created is not the file that is opened.

Compliant Solution (Files)

This compliant solution uses the java.nio.file.Files.newOutputStream() method to atomically create the file and throw an exception if the file already exists:

try (OutputStream out = new BufferedOutputStream(
       Files.newOutputStream( Paths.get(filename),
                              StandardOpenOption.CREATE_NEW))) {
        // Work with out
} catch (IOException x) {
  // File not writable...handle error
}

Applicability

The ability to determine if an existing file has been opened or a new file has been created provides greater assurance that a file other than the intended file is not opened or overwritten.

Bibliography

 


  • No labels