Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: REM Cost Reform

...

Noncompliant Code Example (Reopen)

The following This noncompliant code example opens a file for writing, closes it, opens the same named file for reading, and then closes it again. The logic relies solely on the file name to identify the file.

Code Block
bgColor#FFCCCC
langc
char *file_name;

/* Initialize file_name */

FILE *fd = fopen(file_name, "w");
if (fd == NULL) {
  /* Handle error */
}

/*... writeWrite to file ...*/

fclose(fd);
fd = NULL;

/*
 * A race condition here allows for an attacker to switch 
 * to switch out the file for another. 
 */

/* ... */

fd = fopen(file_name, "r");
if (fd == NULL) {
  /* Handle error */
}

/*... readRead from file ...*/

fclose(fd);
fd = NULL;

...

Code Block
bgColor#ccccff
langc
struct stat orig_st;
struct stat new_st;
char *file_name;

/* Initialize file_name */

int fd = open(file_name, O_WRONLY);
if (fd == -1) {
  /* Handle error */
}

/*... writeWrite to file ...*/

if (fstat(fd, &orig_st) == -1) {
  /* Handle error */
}
close(fd);
fd = -1;

/* ... */

fd = open(file_name, O_RDONLY);
if (fd == -1) {
  /* Handle error */
}

if (fstat(fd, &new_st) == -1) {
  /* Handle error */
}

if ((orig_st.st_dev != new_st.st_dev) ||
    (orig_st.st_ino != new_st.st_ino)) {
  /* fileFile was tampered with! */
}

/*... readRead from file ...*/

close(fd);
fd = -1;

...

Call the fstat() function on a file that is already opened instead of calling stat() on a file name followed by open(). This Doing so ensures that the file for which the information is being collected is the same file that is already opened. See FIO01-C. Be careful using functions that use file names for identification for more information on avoiding race conditions resulting from the use of file names for identification.

...

A simpler solution is to not reopen the file. In this code example, the file is opened once for both writing and reading. Once writing is complete, the fseek() function resets the file pointer to the beginning of the file, and its contents are read back. (See void FIO07-C. Prefer fseek() to rewind().)

Because the file is not reopened, the possibility of an attacker tampering with the file between the writes and subsequent reads is eliminated.

Code Block
bgColor#ccccff
langc
char *file_name;
FILE *fd;

/* Initialize file_name */

fd = fopen(file_name, "w+");
if (fd == NULL) {
  /* Handle error */
}

/*... writeWrite to file ...*/

/* goGo to beginning of file */
fseek(fd, 0, SEEK_SET);

/*... readRead from file ...*/

fclose(fd);
fd = NULL;

...

In this noncompliant code example, the programmer's intent is to open a file for reading, but only if the user running the process owns the specified file. This requirement is a more restrictive requirement than that imposed by the operating system, which requires only that the effective user have permissions to read the file. The code, however, relies solely on the file name to identify the file.

...

Code Block
bgColor#ccccff
langc
struct stat st;
char *file_name;

/* Initialize file_name */

int fd = open(file_name, O_RDONLY);
if (fd == -1) {
  /* Handle error */
}

if ((fstat(fd, &st) == -1) ||
   (st.st_uid != getuid()) ||
   (st.st_gid != getgid())) {
  /* fileFile does not belong to user */
}

/*... readRead from file ...*/

close(fd);
fd = -1;

...

Risk Assessment

Many file-related vulnerabilities are exploited to cause a program to access an unintended file. Proper file identification is necessary to prevent exploitation.

Recommendation

Severity

Likelihood

Detectable

Remediation Cost

Repairable

Priority

Level

FIO05-C

Medium

medium

Probable

probable

No

medium

No

P8

P4

L2

L3

Automated Detection

Tool

Version

Checker

Description

Compass/ROSE

 

 



Could report possible violations of this rule merely by reporting any open() or fopen() call that did not have a subsequent call to fstat()

.

LDRA tool suite
Include Page
LDRA_V
LDRA_V
44 SEnhanced Enforcement

Related Vulnerabilities

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

Related Guidelines

SEI CERT C++
Secure
Coding StandardVOID FIO05-CPP. Identify files using multiple file attributes
ISO/IEC TR 24772:2013Path Traversal [EWR]
MITRE CWECWE-37, Path issue—Slash absolute path
CWE-38, Path Issue—Backslash absolute path
CWE-39, Path Issue—Drive letter or Windows volume
CWE-62, UNIX hard link
CWE-64, Windows shortcut following (.LNK)
CWE-65, Windows hard link

Bibliography

[Drepper 2006]Section 2.2.1 "Identification when Opening"
[
Open Group 2004]
IEEE Std 1003.1:2013]System Interfaces: open
System Interfaces: fstat
"The open Function"
"The fstat Function"
[Seacord
2005a
2013]Chapter
7
8, "File I/O"

...


...

Image Modified Image Modified Image Modified