Programmers frequently create temporary files in directories that are writable by everyone (examples are /tmp
and /var/tmp
on UNIX and C:\TEMP
%TEMP%
on Windows) and may be purged regularly (for example, every night or during reboot).
...
- Use other low-level IPC (interprocess communication) mechanisms such as sockets or shared memory.
- Use higher-level IPC mechanisms such as remote procedure calls.
- Use a secure directory or a jail that can be accessed only by application instances (making sure ensuring that multiple instances of the application running on the same platform do not compete).
...
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 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. It is almost identical to the tmpnam()
function except for an added maxsize
argument for the supplied buffer.
Code Block | ||||
---|---|---|---|---|
| ||||
#define __STDC_WANT_LIB_EXT1__ #include <stdio.h> void func(void) { char file_name[L_tmpnam_s]; int fd; if (tmpnam_s(file_name, L_tmpnam_s) != 0) { /* Handle error */ } /* A TOCTOU race condition exists here */ fd = open(file_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600); if (fd < 0) { /* Handle error */ } } |
Nonnormative text in TR 24731-1 in the C Standard, subclause K.3.5.1.2 [ISO/IEC TR 24731-1:20079899:2011] also recommends the following:
...
If implemented, this reduces the space for unique names and increases the predictability of the resulting names. In general, TR 24731-1 does 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).
...
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 Xwith 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. The number of unique file names mktemp()
can return depends on the number of X's provided.
Code Block | ||||
---|---|---|---|---|
Code Block | ||||
| ||||
#include <stdio.h> #include <stdlib.h> void func(void) { char file_name[] = "tmp-XXXXXX"; int fd; if (!mktemp(file_name)) { /* Handle error */ } /* A TOCTOU race condition exists here */ fd = open(file_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600); if (fd < 0) { /* Handle error */ } } |
...
Noncompliant Code Example (tmpfile()
)
The C 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.
It should be possible to open at least TMP_MAX
temporary files during the lifetime of the program. (This limit may be shared with tmpnam()
.) Subclause 7.21.4.4 of paragraph 6 of the C Standard allows for the value of the macro TMP_MAX
to be as small as 25.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> void func(void) { FILE *fp = tmpfile(); if (fp == NULL) { /* Handle error */ } } |
Noncompliant Code Example (tmpfile_s()
,
...
Annex K)
The The ISO/IEC TR 24731-1 function 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.
...
It should be possible to open at least TMP_MAX_S
temporary files during the lifetime of the program. (This limit may be shared with tmpnam_s()
.) The value of the macro TMP_MAX_S
is required to be only 25 [ISO/IEC TR 24731-1:20079899:2011].
TR 24731-1 notes The C Standard subclause K3.5.1.2 paragraph 7 notes the following regarding the use of tmpfile_s()
instead of tmpnam_s()
[ISO/IEC TR 24731-1:20079899:2011]:
After a program obtains a file name using the the
tmpnam_s
function and before the program creates a file with that name, the possibility exists that someone else may create a file with that same name. To avoid this race condition, the thetmpfile_s
function should be used instead of oftmpnam_s
when possible. One situation that requires the use of the thetmpnam_s
function is when the program needs to create a temporary directory rather than a temporary file.
Code Block | ||||
---|---|---|---|---|
| ||||
#define __STDC_WANT_LIB_EXT1__ #include <stdio.h> void func(void) { FILE *fp; if (tmpfile_s(&fp)) { /* Handle error */ } } |
The TR24731-1 The tmpfile_s()
function should not be used with implementations that create temporary files in 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.
...
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 PID 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 TR24731-1 EX0: The Annex K tmpfile_s()
function can be used if all the targeted implementations create temporary files in secure directories.
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
FIO43-C | High | Probable | Medium | P12 | L1 |
The
unlink()
function doesn't follow symlinks and doesn't really have much of an affect on hard links. So, I guess your options for attacking something like that would be:
*SIGSTOP
orSIGTSTP
it before the unlink, maybe unlink it yourself and wait (a while) until something created something with the same name, or try to use that name somehow. Probably not that useful, but maybe in a specific attack it could work with a lot of effort.
*You could sorta do a symlink attack with an intermediate path component, for example, if it was/tmp/tmp2/ed.XXXXXX
, you couldrm tmp2
and then symlink it to/etc
or something. It would thenrm /etc/ed.XXXXXX
, but that probably wouldn't buy you much.John McDonald
Automated Detection
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
|
| Can detect violations of this recommendation. Specifically, Rose reports use of | |||||||
Tool | Version | Checker | Description | ||||||
|
| Can detect violations of this recommendation. Specifically, Rose reports use of | |||||||
Coverity | 6.5 | SECURE_TEMP | Fully Implemented | ||||||
| 489 S | Partially implemented | |||||||
PRQA QA-C |
| warncall tmpnam, tmpfile, mktemp, tmpnam_s | Partially implemented |
...
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...
the CERT website.
Related Guidelines
CERT C Secure Coding Standard | FIO15-C. Ensure that file operations are performed in a secure directory | |||
CERT C++ Secure Coding Standard | FIO43-CPP. Do not create temporary files in shared directories | |||
CERT Oracle Secure Coding Standard for Java | FIO03-J. Remove temporary files before termination | ISO/IEC TR 24731-1:2007 | Subclause 6.5.1.1, "TheCoding Standard for Java | FIO03-J. Remove temporary files before termination |
ISO/IEC TR 24772:2013 | Path Traversal [EWR] | |||
MITRE CWE | CWE-379, Creation of temporary file in directory with insecure permissions |
...
[Austin Group 2008] | |
[HP 2003] | |
[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] | mktemp() mkstemp() 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" |
...