Wiki Markup |
---|
The C99 {{fopen()}} function is used to open an existing file or create a new one \[[ISO/IEC 9899:1999|AA. C References#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: fopen()
In this example, the file referenced by file_name
is opened for writing. This example is non-compliant noncompliant if the programmer's intent was to create a new file, but the referenced file already exists.
Code Block | ||
---|---|---|
| ||
char *file_name; FILE *fp; /* initialize file_name */ fp = fopen(file_name, "w"); if (!fp) { /* handle error */ } |
...
Noncompliant Code Example: fopen_s()
(ISO/IEC TR 24731-1)
Wiki Markup |
---|
The ISO/IEC TR 24731-1 {{fopen_s()}} function is designed to improve the security of the {{fopen()}} function \[[ISO/IEC TR 24731-1:2007|AA. C References#SO/IEC TR 24731-1-2007]\]. However, like {{fopen()}}, {{fopen_s()}} provides no mechanism to determine if an existing file has been opened for writing or a new file has been created. |
Code Block | ||
---|---|---|
| ||
char *file_name; FILE *fp; /* initialize file_name */ errno_t res = fopen_s(&fp, file_name, "w"); if (res != 0) { /* handle error */ } |
Compliant Solution: open()
(POSIX)
Wiki Markup |
---|
The {{open()}} function as defined in the Open Group Base Specifications Issue 6 \[[Open Group 04|AA. C References#Open Group 04]\] is available on many platforms and provides finer control than {{fopen()}}. In particular, {{fopen()}} accepts the {{O_CREAT}} and {{O_EXCL}} flags. When used together, these flags instruct the {{open()}} function to fail if the file specified by {{file_name}} already exists. |
...
For examples on how to check for the existence of a file without opening it, see FIO10-AC. Take care when using the rename() function.
Compliant Solution: fopen()
(GNU)
Wiki Markup |
---|
Section 12.3 of the GNU C Library says: \[[Loosemore 07|AA. C References#Loosemore 07]\] |
...
Use of this (non-portable) extension allows for the easy remediation of legacy code.
Compliant Solution: fdopen()
(POSIX)
Wiki Markup |
---|
For code that operates on {{FILE}} pointers and not file descriptors, the POSIX {{fdopen()}} function can be used to associate an open stream with the file descriptor returned by {{open()}}, as shown in this compliant solution \[[Open Group 04|AA. C References#Open Group 04]\]. |
Code Block | ||
---|---|---|
| ||
char *file_name; int new_file_mode; FILE *fp; int fd; /* initialize file_name and new_file_mode */ fd = open(file_name, O_CREAT | O_EXCL | O_WRONLY, new_file_mode); if (fd == -1) { /* Handle Error */ } fp = fdopen(fd, "w"); if (fp == NULL) { /* Handle Error */ } |
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 upon.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
FIO03-A C | medium | probable | high | P4 | L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.19.3, "Files," and Section 7.19.4, "Operations on Files" \[[ISO/IEC TR 24731-1:2007|AA. C References#SO/IEC TR 24731-1-2007]\] Section 6.5.2.1, "The {{fopen_s}} function" \[[Loosemore 07|AA. C References#Loosemore 07]\] [Section 12.3, "Opening Streams"|http://www.gnu.org/software/libc/manual/html_node/Opening-Streams.html] \[[Open Group 04|AA. C References#Open Group 04]\] \[[Seacord 05a|AA. C References#Seacord 05]\] Chapter 7, "File I/O" |
...
FIO02-C. Canonicalize path names originating from untrusted sources 09. Input Output (FIO) FIO04-AC. Detect and handle input and output errors