Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Parasoft Jtest 2021.1

...

  • Share data between processes.
  • Store auxiliary program data (for example, to save preserve memory).
  • Construct and/or load classes, JAR files, and native libraries dynamically

...

  • .

...

Temporary files are files and consequently must conform to the requirements specified by other rules governing operations on files, including FIO00-J. Do not overwrite an existing file while attempting to create a new file, FIO03operate on files in shared directories and FIO01-J. Create files with appropriate access permissions, and FIO04-J. Do not operate on files in shared directories. Temporary files have an the additional requirement that they must be removed before program 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 daemonprocess. However, these utilities are themselves frequently vulnerable to file-based exploits.

Noncompliant Code Example

This and may require the use of secure directories. subsequent code examples assume that files are created in a secure directory in compliance with FIO00-J. Do not operate on files in shared directories and are created with proper access permissions in compliance with FIO01-J. Create files with appropriate access permissions. Both requirements may be managed outside the Java Virtual Machine (JVM).

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
        }
      }
    }
  }
}

Noncompliant Code Example (createTempFile(), deleteOnExit())

This noncompliant code example invokes the File.createTempFile() method to generate , which generates a unique temporary filename file name based on two parameters, : a prefix and an extension. This is the only method currently designed and provided for producing from Java 6 and earlier that is designed to produce unique file names; , although the names produced can be easily predicted. This can be solved by using a good A random number generator can be used to produce the prefix .

Providing unique filenames is a common attempt at mitigating the risk of creating a file in an insecure or shared directory. If the filename is not sufficiently unique or random, an attacker can guess or predict the name of the file to be created, and create a symbolic link with the same name, the final target of which is a file selected by the attacker.

if a random file name is required.

This example also uses the deleteOnExit() method to ensure that the temporary file is deleted when the JVM terminates. However, according to the Java API [API 2014] Class File, method deleteOnExit() documentation, Wiki MarkupThis example also attempts to use the {{deleteOnExit()}} method to ensure that the temporary file is deleted when the JVM terminates. However, according to the Java API \[[API 2006|AA. Bibliography#API 06]\] Class {{File}}, method {{deleteOnExit()}} documentation:

Deletion will be attempted only for normal termination of the virtual machine, as defined by the Java Language Specification. Once deletion has been requested, it is not possible to cancel the request. This method should consequently therefore be used with care.
Note: this method should not be used for file-locking, as the resulting protocol cannot be made to work reliably.

...

Consequently, the file is not deleted if the JVM terminates unexpectedly. A longstanding bug on Windows -based systems , reported as [Bug ID: 4171239|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id= 4171239] \ [[SDN 2008|AA. Bibliography#SDN 08]\] causes JVMs to fail to delete a file when {{deleteOnExit()}} is invoked before the associated stream or {{RandomAccessFile}} is closed. ], 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";
    try {
      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
    }
  }       
}

Noncompliant Code Example (POSIX, Java 1.7), DELETE_ON_CLOSE)

...

if

...

Code Block
bgColor#FFcccc

class TempFile {
  public static void main(String[] args) {
    // POSIX file permissions for exclusive read/write
    Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");
    FileAttribute att = PosixFilePermissions.asFileAttribute(perms);
    Path tempFile = null;
    try (fop != null) {
      tempFile = Files.createTempFile("file", ".myapp", att);
      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) {
fop.close();
        System.err.println("File exists: " + tempFile);
    } catch (IOException x) {
      // Some other sort of// failure,Handle sucherror
 as permissions.
      System.err.println("Error creating temporary file: " + x);}
      }
    }
  }
}

Despite the new Java 1.7 features, this example still has several vulnerabilities. There is no mechanism to open the file with exclusive access, a feature provided by standard POSIX. Consequently the temporary file, once created, is still accessible and modifiable by anyone with access to its containing directory. Also, because the creation of the file and the opening of the file are distinct operations, this program is still vulnerable to a time-of-check-time-of-use (TOCTOU) race condition.

Wiki Markup
To work around the file/stream termination issue, always attempt to terminate the resource normally before invoking {{deleteOnExit()}}. Using {{File.io.delete()}} to immediately delete the file is good practice when possible and avoids improper JVM termination related issues. 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] \[[SDN 2008|AA. Bibliography#SDN 08]\]. There is no known workaround for this case.

Compliant Solution (POSIX, Java 1.7, secure directory)

Compliant Solution (DELETE_ON_CLOSE)

This compliant solution creates a temporary file using several methods from Java's NIO.2 package (introduced in Java SE 7). 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 DELETE_ON_CLOSE option, which removes the file automatically when it is closedThis compliant solution uses the isInSecureDir() method to ensure that an attacker cannot tamper with the temporary file. Note that once the path name of a directory has been checked using isInSecureDir(), all further file operations on that directory must be performed using the same path name.

Code Block
bgColor#ccccff

class TempFile {
  public static boolean isInSecureDir(Path file) {
    // ...
  }

  public static void main(String[] args) {
    Path tempDir = new File(args[0]).toPath();
    if (!isInSecureDir(tempDir)) {
      System.out.println("Temporary Directory not secure");
      return;
    }

    // POSIX file permissions for exclusive read/write
    Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");
    FileAttribute att = PosixFilePermissions.asFileAttribute(perms);
    Path tempFile = null;
    try {
      tempFile = Files.createTempFile(tempDir, "filetempnam", ".myapptmp", att);
      try (BufferedWriter writer =
          Files.newBufferedWriter(tempFile, Charset.forName("UTF8"),
                                                           StandardOpenOption.DELETE_ON_CLOSE)) {
          // writeWrite 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);
    }
  }
}

Compliant Solution

Vulnerabilities When a secure directory for storing temporary files is not available, the vulnerabilities that result from using shared temporary files in insecure directories can be avioded avoided by using other alternative mechanisms, including:

  • other Other IPC mechanisms such as sockets and remote procedure calls.
  • the The low-level Java Native Interface (JNI).
  • memory Memory-mapped files.
  • threads Threads to share heap data within the same JVM (applies to data sharing between Java processes only)a secure directory that can be accessed only by application instances, provided that multiple instances of the application running on the same platform avoid competing for the same files.

Exceptions

FIO07-EX0: Programs that operate on single user systems, or on systems where there are no shared directories or no possibility of file system vulnerabilities, do not need to ensure that temporary files are only created in secure directories.

Risk Assessment

Failure to follow best practices while creating, using and deleting remove temporary files can lead to denial of service vulnerabilities, misinterpretations and alterations in control flowbefore termination can result in information leakage and resource exhaustion.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO07-J

high

probable

medium

P12

L1

FIO03-J

Medium

Probable

Medium

P8

L2

Automated Detection

ToolVersionCheckerDescription
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.FIO03.ATF
CERT.FIO03.REMTMP
Avoid temporary files
Remove temporary files before termination

Related Guidelines

Bibliography

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8355ad2f-2c18-4f91-8725-fa1f7c69511d"><ac:plain-text-body><![CDATA[

[

[API 2006AA. Bibliography#API 06]]

API 2014]

Class File

, methods createTempFile, delete, deleteOnExit

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a5dbaa9f-b011-4bd0-b932-50f474901144"><ac:plain-text-body><![CDATA[

[[CVE 2008

AA. Bibliography#CVE 08]]

[CVE-2008-5354

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5354]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="912da1c1-a4fb-4be0-a7a8-c91244e11caa"><ac:plain-text-body><![CDATA[

[[Darwin 2004

AA. Bibliography#Darwin 04]]

11.5 Creating a Transient File

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1eefd070-0947-4130-a102-0bd79f419171"><ac:plain-text-body><![CDATA[

[[J2SE 2011

AA. Bibliography#J2SE 11]]

 

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="02b18d06-1977-484b-9661-b36a2927292f"><ac:plain-text-body><![CDATA[

[[SDN 2008

AA. Bibliography#SDN 08]]

Bug IDs: 4171239, 4405521, 4635827, 4631820

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="fd5bc23e-0906-40d3-9983-d638ba76d366"><ac:plain-text-body><![CDATA[

[[Secunia 2008

AA. Bibliography#Secunia 08]]

[Secunia Advisory 20132

http://secunia.com/advisories/20132/]

]]></ac:plain-text-body></ac:structured-macro>


   Method createTempFile
   Method delete
   Method deleteOnExit

[Darwin 2004]

Section 11.5, "Creating a Transient File"

[J2SE 2011]


[JDK Bug 2015]

Bug JDK-4405521
Bug JDK-4631820

[SDN 2008]Bug ID: 4171239 

[Secunia 2008]

Secunia Advisory 20132


...

Image Added Image Added Image AddedFIO06-J. Close resources when they are no longer needed      12. Input Output (FIO)      FIO08-J. Do not log sensitive information outside a trust boundary