Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Edited by sciSpider v2.4 (sch jbop) (X_X)@==(Q_Q)@

...

Removing temporary files when they are no longer required allows file names and other resources (such as secondary storage) to be recycled. In the case of abnormal termination, there is no sure method that can guarantee the removal of orphaned files. For this reason, temporary file cleaner utilities, which are invoked manually by a system administrator or periodically run by a daemon to sweep temporary directories and remove old files, are widely used. However, these utilities are themselves vulnerable to file-based exploits, and often require the use of shared directories. During normal operation, it is the responsibility of the program to ensure that temporary files are removed either explicitly, or through the use of library routines such as tmpfile_s which guarantee temporary file deletion upon program termination.

...

Noncompliant Code Example: fopen()/open() with tmpnam()

This non-compliant noncompliant code example creates a file with a hard coded file_name (presumably in a shared directory such as /tmp or C:\Temp).

...

Because the name is hard coded and consequently neither unique nor unpredictable, an attacker need only place a symbolic link in lieu of the file and the target file referenced by the link is opened and truncated.

Wiki Markup
The following non-compliantnoncompliant code example attempts to remedy the problem by generating the file name at runtime using {{tmpnam()}}.  The C99 {{tmpnam()}} function generates a string that is a valid file name and that is not the same as the name of an existing file \[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\]. Files created using strings generated by the {{tmpnam()}} function are temporary in that their names should not collide with those generated by conventional naming rules for the [implementation|BB. Definitions#implementation].  The function is potentially capable of generating {{TMP_MAX}} different strings, but any or all of them may already be in use by existing files.

...

Because tmpnam() does not guarantee a unique name and fopen() does not provide a facility for an exclusive open, this code is still vulnerable.

Wiki Markup
This next non-compliantnoncompliant code example attempts to remedy the problem by using the POSIX {{open()}} function, and providing a mechanism to indicate whether an existing file has been opened for writing or a new file has been created \[[Open Group 04|AA. C References#Open Group 04]\]. If the {{O_CREAT}} and {{O_EXCL}} flags are used together, the {{open()}} function fails when the file specified by {{file_name}} already exists. To prevent an existing file from being opened and truncated, include the flags {{O_CREAT}} and {{O_EXCL}} when calling {{open()}}.

...

  • O_SHLOCK Atomically obtain a shared lock.
  • O_EXLOCK Atomically obtain an exclusive lock.

...

Noncompliant Code Example: tmpnam_s() (ISO/IEC TR 24731-1)

Wiki Markup
The TR 24731-1 {{tmpnam_s()}} function generates a string that is a valid file name and that is not the same as the name of an existing file \[[ISO/IEC TR 24731-1:2007|AA. C References#SO/IEC TR 24731-1-2007]\]. It is almost identical to the {{tmpnam}} function above except with an added {{maxsize}} argument for the supplied buffer.

...

If implemented, this reduces the space for unique names and increases the predictability of the resulting names. But in general, TR 24731-1 does not establish any criteria for the predictability of names. For example, the name generated by the tmpnam_s function from Microsoft Visual Studio 2005 consists of a program-generated file name and, after the first call to tmpnam_s(), a file extension of sequential numbers in base 32 (.1-.1vvvvvu, when TMP_MAX_S in stdio.h is INT_MAX).

...

Noncompliant Code Example: mktemp()/open() (POSIX)

The POSIX function mktemp() takes a given file name template and overwrites a portion of it to create a file name. The template may be any file name with some number of Xs appended to it (for example, /tmp/temp.XXXXXX). The trailing Xs are replaced with the current process number and/or a unique letter combination. The number of unique file names mktemp() can return depends on the number of Xs provided.

...

Never use mktemp(). Some implementations follow BSD 4.3 and replace XXXXXX by the current process id and a single letter, so that at most 26 different names can be returned. Since on the one hand the names are easy to guess, and on the other hand there is a race between testing whether the name exists and opening the file, every use of mktemp() is a security risk. The race is avoided by mkstemp(3).

...

Noncompliant Code Example: tmpfile()

The C99 tmpfile() function creates a temporary binary file that is different from any other existing file and that is automatically removed when it is closed or at program termination.

...

Code Block
bgColor#FFCCCC
FILE* fp = tmpfile();
if (fp == NULL) {
  /* Handle error */
}

...

Noncompliant Code Example: tmpfile_s() (ISO/IEC TR 24731-1)

The ISO/IEC TR 24731-1 function tmpfile_s() creates a temporary binary file that is different from any other existing file and that is automatically removed when it is closed or at program termination. If the program terminates abnormally, whether an open temporary file is removed is implementation-defined.

...

A call to mkstemp() replaces the six Xs in the template string with six randomly selected characters and returns a file descriptor for the file (opened for reading and writing) as in this compliant solution.

Code Block
bgColor#ccccff
const char const *sdn = "/home/usr1/";
char sfn[] = "/home/usr1/temp-XXXXXX";
FILE *sfp;

if (!secure_dir(sdn)) {
  /* Handle error */
}

int fd = mkstemp(sfn);
if (fd == -1) {
  /* Handle error */
}

/*
 * Unlink immediately to hide the file name.
 * The race condition here is inconsequential if the file
 * is created with exclusive permissions (glibc >= 2.0.7)
 */

if (unlink(sfn) == -1) {
  /* Handle Error */
}

sfp = fdopen(fd, "w+");
if (sfp == NULL) {
  close(fd);
  /* Handle error */
}

/* use temporary file */

fclose(sfp); /* also closes fd */

...

Automated Detection

Compass/ROSE is able to can detect violations of this recommendation. Specifically, Rose reports use of tmpnam(), tmpnam_s(), tmpfile(), and mktemp().

...