Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: removed irrelevant intro text

...

  • share data between processes.
  • store auxiliary program data (for example, to preserve memory).
  • construct and/or load classes, JAR files, and native libraries dynamically.

Programmers frequently create temporary files in directories that are writable by everyone; examples include /tmp and /var/tmp on POSIX and C:\TEMP on Windows. Files in such directories may be purged regularly, such as every night or during reboot. However, an attacker who has access to the local file system can exploit operations on files in shared directories when those files are created insecurely or remain accessible after use. For example, an attacker who can both predict the name of a temporary file and change or replace that file can exploit a (TOCTOU) race condition to cause a failure in creating the temporary file from within program code or to cause the program to operate on a file determined by the attacker. This exploit is particularly dangerous when the vulnerable process is running with elevated privileges because the attacker can operate on any file accessible by the vulnerable process. On multiuser systems, a user can be tricked by an attacker into unintentionally operating on the user's own files. Consequently, temporary file management must comply with rule FIO00-J. Do not operate on files in shared directories.

Many programs that create temporary files attempt to give them unique and unpredictable file names. This is a common attempt at mitigating the risk of creating a file in an insecure or shared directory. If the file name is predictable, an attacker could guess or predict the name of the file to be created and could create a link with the same name to a normally inaccessible file. However, when temporary files are created in a secure directory, an attacker cannot tamper with them. Consequently, the need for unpredictable names is eliminated.

Temporary files are files and consequently must conform to the requirements specified by other rules governing operations on files, including rules FIO00-J. Do not operate on files in shared directories and FIO01-J. Create files with appropriate access permissions. Furthermore, temporary files have the additional requirement that they must be removed before program termination.

...

This noncompliant code example fails to remove the file upon completion.

Code Block
bgColor#FFcccc

class TempFile {
  public static void main(String[] args) throws IOException{
    File f = new File("tempnam.tmp");
    if (f.exists()) {
      System.out.println("This file already exists");
      return;
    }

    FileOutputStream fop = null;
    try {
      fop = new FileOutputStream(f);
      String str = "Data";
      fop.write(str.getBytes());
    } finally {
      if (fop != null) {
        try {
          fop.close();
        } catch (IOException x) {
          // handle error
        }
      }
    }
  }
}

...

Consequently, the file is not deleted if the JVM terminates unexpectedly. A longstanding bug on Windows-based systems reported as Bug ID: 4171239 [SDN 2008] causes JVMs to fail to delete a file when deleteOnExit() is invoked before the associated stream or RandomAccessFile is closed.

Code Block
bgColor#FFcccc

class TempFile {
  public static void main(String[] args) throws IOException{
    File f = File.createTempFile("tempnam",".tmp");
    FileOutputStream fop = null;
    try {
      fop = new FileOutputStream(f);
      String str = "Data";
      fop.write(str.getBytes());
      fop.flush();
    } finally {
      // Stream/file still open; file will
      // not be deleted on Windows systems
      f.deleteOnExit(); // Delete the file when the JVM terminates

      if (fop != null) {
        try {
          fop.close();
        } catch (IOException x) {
          // handle error
        }
      }
    }
  }
}

...

This compliant solution creates a temporary file using several methods from Java SE 7's NIO2 package. It uses the createTempFile() method, which creates an unpredictable name. (The actual method by which the name is created is implementation-defined and undocumented.) The file is opened using the try-with-resources construct, which automatically closes the file regardless of whether an exception occurs. Finally, the file is opened with the Java SE 7 DELETE_ON_CLOSE option, which removes the file automatically when it is closed.

Code Block
bgColor#ccccff

class TempFile {
  public static void main(String[] args) {
    Path tempFile = null;
    try {
      tempFile = Files.createTempFile("tempnam", ".tmp");
      try (BufferedWriter writer =
          Files.newBufferedWriter(tempFile, Charset.forName("UTF8"),
                                  StandardOpenOption.DELETE_ON_CLOSE)) {
        // write to file
      }
      System.out.println("Temporary file write done, file erased");
    } catch (FileAlreadyExistsException x) {
      System.err.println("File exists: " + tempFile);
    } catch (IOException x) {
      // Some other sort of failure, such as permissions.
      System.err.println("Error creating temporary file: " + x);
    }
  }
}

...

[API 2006]

Class File, methods createTempFile, delete, deleteOnExit

[Darwin 2004]

11.5, Creating a Transient File

[J2SE 2011]

 

[SDN 2008]

Bug IDs 4171239, 4405521, 4635827, 4631820

[Secunia 2008]

Secunia Advisory 20132

 

      12. Input Output (FIO)