Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The following table lists common temporary file functions and their respective conformance to these criteria:

Conformance of File Functions to Criteria for Temporary Files

 

tmpnam
(C)

tmpnam_s
(Annex K)

tmpfile
(C)

tmpfile_s
(Annex K)

mktemp
(POSIX)

mkstemp
(POSIX)

Unpredictable Name

Not portably

Yes

Not portably

Yes

Not portably

Not portably

Unique Name

Yes

Yes

Yes

Yes

Yes

Yes

Atomic open

No

No

Yes

Yes

No

Yes

Exclusive Access

Possible

Possible

No

If supported by OS

Possible

If supported by OS

Appropriate Permissions

Possible

Possible

No

If supported by OS

Possible

Not portably

File Removed

No

No

Yes*

Yes*

No

No

...

Securely creating temporary files is error prone and dependent on the version of the C runtime library used, the operating system, and the file system. Code that works for a locally mounted file system, for example, may be vulnerable when used with a remotely mounted file system. Moreover, none of these functions are without problems. The only secure solution is to not create temporary files in shared directories.

Unique and Unpredictable File Names

Privileged programs that create temporary files in world-writable directories can be exploited to overwrite protected system files. An attacker who can predict the name of a file created by a privileged program can create a symbolic link (with the same name as the file used by the program) to point to a protected system file. Unless the privileged program is coded securely, the program will follow the symbolic link instead of opening or creating the file that it is supposed to be using. As a result, a protected system file to which the symbolic link points can be overwritten when the program is executed [HP 2003]. Unprivileged programs can be similarly exploited to overwrite protected user files.

Exclusive Access

Exclusive access grants unrestricted file access to the locking process while denying access to all other processes and eliminates the potential for a race condition on the locked region. (See Secure Coding in C and C++, Chapter 8[Seacord 2013].)

...

  • Mandatory locking works only on local file systems and does not extend to network file systems (such as NFS or AFS).
  • File systems must be mounted with support for mandatory locking, and this is disabled by default.
  • Locking relies on the group ID bit that can be turned off by another process (thereby defeating the lock).

Removal before Termination

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 noncompliant code example creates a file with a hard-coded file_name (presumably in a shared directory such as /tmp or C:\Temp):

...

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

Noncompliant Code Example (tmpnam_s()/open(), Annex K, POSIX)

The C Standard function 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. It is almost identical to the tmpnam() function except for an added maxsize argument for the supplied buffer.

...

If implemented, the space for unique names is reduced and the predictability of the resulting names is increased. In general, Annex K does not establish any criteria for the predictability of names. For example, the name generated by the tmpnam_s function from Microsoft Visual Studio 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).

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 exactly six X's appended to it (for example, /tmp/temp.XXXXXX). The six trailing X's are replaced with the current process number and/or a unique letter combination.

...

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 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
langc
#include <stdio.h>
 
void func(void) {
  FILE *fp = tmpfile();
  if (fp == NULL) {
    /* Handle error */
  }
}

Noncompliant Code Example (tmpfile_s(), Annex K)

The tmpfile_s() function creates a temporary binary file that is different from any other existing file and 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.

...

The tmpfile_s() function should not be used with implementations that create temporary files in a shared directory, such as /tmp or C:, because the function does not allow the user to specify a directory in which the temporary file should be created.

Compliant Solution (mkstemp(), POSIX)

The mkstemp() algorithm for selecting file names has shown to be immune to attacks. The mkstemp() function is available on systems that support the Open Group Base Specifications Issue 4, version 2 or later.

...

This compliant solution invokes the user-defined function secure_dir() (such as the one defined in FIO15-C. Ensure that file operations are performed in a secure directory) to ensure the temporary file resides in a secure directory.

Implementation Details

For GLIBC, versions 2.0.6 and earlier, the file is created with permissions 0666; for GLIBC, versions 2.0.7 and later, the file is created with permissions 0600. On NetBSD, the file is created with permissions 0600. This creates a security risk in that an attacker will have write access to the file immediately after creation. Consequently, programs need a private version of the mkstemp() function in which this issue is known to be fixed.

In many older implementations, the name is a function of process ID and time, so it is possible for the attacker to predict the name and create a decoy in advance. FreeBSD changed the mk*temp() family to eliminate the process ID component of the file name and replace the entire field with base-62 encoded randomness. This raises the number of possible temporary files for the typical use of six X's significantly, meaning that even mktemp() with six X's is reasonably (probabilistically) secure against guessing except under frequent usage [Kennaway 2000].

Exceptions

FIO43-EX1: The Annex K tmpfile_s() function can be used if all the targeted implementations create temporary files in secure directories.

Risk Assessment

Insecure temporary file creation can lead to a program accessing unintended files and permission escalation on local systems.

RuleRecommendation

Severity

Likelihood

Remediation Cost

Priority

Level

FIO43FIO21-C

High

Probable

Medium

P12

L1

 Automated Detection

Tool

Version

Checker

Description

Compass/ROSE

 

 

Can detect violations of this recommendation. Specifically, Rose reports use of tmpnam(), tmpnam_s(), tmpfile(), and mktemp()

Coverity6.5SECURE_TEMPFully Implemented

LDRA tool suite

Include Page
LDRA_V
LDRA_V

489 S

Partially implemented

PRQA QA-C
Include Page
PRQA_V
PRQA_V
warncall tmpnam, tmpfile, mktemp, tmpnam_sPartially implemented

Related Vulnerabilities

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

Related Guidelines

Bibliography

[HP 2003] 
[IEEE Std 1003.1:2013]XSH, System Interfaces: open
XSH, System Interfaces: mkdopen, mksopen
[ISO/IEC 9899:2011]Subclause K.3.5.1.2, "The tmpnam_s Function"
Subclause 7.21.4.4, "The tmpnam Function
[Kennaway 2000] 
[Open Group 2004]mkstemp()
mktemp()

open()
[Seacord 2013]Chapter 3, "Pointer Subterfuge"
Chapter 8, "File I/O"
[Viega 2003]Section 2.1, "Creating Files for Temporary Use"
[Wheeler 2003]Chapter 7, "Structure Program Internals and Approach"

...