Many file related security vulnerabilities result from a program accessing a file object different from the one intended. In the C programming language, character-based file names are bound to underlying file objects in name only. File names provide no information regarding the nature of the file object itself. Furthermore, the binding of a file name to a file object is reasserted every time the file name is used in an operation. File descriptors are bound to underlying file objects by the operating system. Operating on files via file descriptors instead file names provides a greater level of certainty with regard to the object that is acted on. Thus, it is recommended that files are accessed through file descriptors, versus filenames.
Non-Compliant Example 1
In this example, the function chmod(...)
is called to set the permissions of a file. However, if the file file_name
has been changed from the time it was opened, the permissions may be changed on a different file then intended.
FILE * f_ptr = fopen(file_name,"w"); f_ptr = fopen(file_name,"w"); if (!f_ptr) { /* Handle fopen() Error */ } ... if (chmod(file_name, new_mode) == -1) { /* Handle chmod() Error */ } /* Process file */
Compliant Solution 1
To correct the error, use functions that operate on file descriptors. This means using open()
in stead of fopen()
and fchmod(...)
instead of chmod(...)
.
fd = open(file_name, O_WRONLY | O_CREAT, 0600); if (fd == -1) { /* Handle open() error */ } ... if (fchmod(fd, new_mode) == -1) { /* Handle chmod() Error */ } /* Process file */
Priority: ?? Level: ??
References
- Seacord 05 Chapter 7, File I/O
- ISO/IEC 9899-1999 Sections 7.19.3, Files
- ISO/IEC 9899-1999 Sections 7.19.4, Operations on Files
- Apple Secure Coding Guide Avoiding Race Conditions and Insecure File Operations