Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: new rule

Java's file-manipulation functions often indicate failure with a return value, rather than throwing an exception. The Java Tutorial for Java 7 notes:

Prior to the Java SE 7 release, the java.io.File class was the mechanism used for file I/O, but it had several drawbacks.

Many methods didn't throw exceptions when they failed, so it was impossible to obtain a useful error message. For example, if a file deletion failed, the program would receive a "delete fail" but wouldn't know if it was because the file didn't exist, the user didn't have permissions, or there was some other problem.

Consequently, it is easy for file operations to fail silently, if the methods' return values are ignored. Therefore, do not ignore return values of file-based methods. (This guideline is a specific instance of EXP00-J. Do not ignore values returned by methods.)

Noncompliant Code Example (delete())

This noncompliant code example attempts to delete the file specified, but gives no indication of its success. The [API 2006] defines File.delete() to only throw a SecurityException, if the program is not authorized to delete the file. No other exceptions are thrown; so it is easy for the deletion to fail, with no indication of why

Wiki Markup
The C99 {{fopen()}} function is used to open an existing file or create a new one \[[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\]. However, {{fopen()}} does not indicate if an existing file has been opened for writing or a new file has been created. This may lead to a program overwriting or accessing an unintended file.

Noncompliant Code Example (FileOutputStream())

In this noncompliant code example, the file referenced by file is opened for writing. This example is noncompliant if the programmer's intent was to create a new file, but the referenced file already exists.

Code Block
bgColor#FFCCCC
StringFile file;
OutputStream out= =/* new FileOutputStream(fileinitialize */
file.delete();

Compliant Solution

...

This compliant solution uses the CREATE_NEW option from Java 1.7, which causes an exception to be thrown if the file being created already exists.checks the return value of delete().

Code Block
bgColor#ccccFF
PathFile file = new File("file").toPath();
try (OutputStream out = Files.newOutputStream( file, StandardOpenOption.CREATE_NEW);) {
  // write to out
};

Noncompliant Code Example (FileWriter())

In this noncompliant code example, the file referenced by file is opened for writing. Again, the example is noncompliant if the programmer's intent was to create a new file, but the referenced file already exists.

Code Block
bgColor#FFCCCC

String file;
Writer out = new FileWriter(file);

Compliant Solution (Java 1.7, StandardOpenOption.CREATE_NEW)

This compliant solution uses the CREATE_NEW option from Java 1.7, which causes an exception to be thrown if the file being created already exists.

args[0]);
if (!file.delete()) {
  System.out.println("Deletion failed");
}

Compliant Solution (Java 1.7)

Wiki Markup
This compliant solution uses the {{Files.delete()}} method from Java 1.7 to delete the file. \[[J2SE 2011|AA. Bibliography#J2SE 11]\] defines {{Files.delete()}} to throw the following exceptions:

NoSuchFileException - if the file does not exist (optional specific exception)
DirectoryNotEmptyException - if the file is a directory and could not otherwise be deleted because the directory is not empty (optional specific exception)
IOException - if an I/O error occurs
SecurityException - In the case of the default provider, and a security manager is installed, the SecurityManager.checkDelete(String) method is invoked to check delete access to the file

Code Block
bgColor#ccccFF
Code Block
bgColor#ccccff
Path file = new File("file").toPath();
try (BufferedWriter{
 out = Files.newBufferedWriterdelete( file, Charset.forName("UTF8"),
                                                   StandardOpenOption.CREATE_NEW););
} catch (IOException x) {
  // writehandle to outerror
};

Risk Assessment

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 acted uponFailure to check file operation errors can result in unexpected behavior.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

FIO00 FIO09-J

medium

probable

high

P4

L3

Automated Detection

TODO

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this guideline on the CERT website.

Related Guidelines

CERT C++ Secure Coding Standard: FIO03FIO04-CPP. Do not make assumptions about fopen() and file creationDetect and handle input and output errors

CERT C Secure Coding Standard: FIO03FIO04-C. Do not make assumptions about fopen() and file creationDetect and handle input and output errors

Bibliography

Wiki Markup
[[API 2006|AA. Bibliography#API 06]\] Class {{InputStreamFile.delete()}}, {{DataInputStream}}
\[[J2SE 2011|AA. Bibliography#J2SE 11]\] The try-with-resources Statement{{Files.delete()}}
\[[Seacord 2005a|AA. Bibliography#Seacord 05]\] Chapter 7, "File I/O"

...