CWE-403: Exposure of File Descriptor to Unintended Control Sphere ('File Descriptor Leak')
Learn about CWE-403 (Exposure of File Descriptor to Unintended Control Sphere ('File Descriptor Leak')), its security impact, exploitation methods, and prevention guidelines.
What is Exposure of File Descriptor to Unintended Control Sphere ('File Descriptor Leak')?
• Overview: A file descriptor leak occurs when a process fails to close sensitive file descriptors before starting a child process, allowing the child process to use the file descriptors without proper authorization.
• Exploitation Methods:
- Attackers can exploit this vulnerability by gaining control of a child process and accessing file descriptors that should be restricted.
- Common attack patterns include privilege escalation and unauthorized data access through inherited file descriptors.
• Security Impact:
- Direct consequences include unauthorized reading or writing of files and other I/O operations.
- Potential cascading effects include privilege escalation, data corruption, and leaking confidential information.
- Business impact can involve data breaches, compliance violations, and reputational damage.
• Prevention Guidelines:
- Specific code-level fixes include explicitly closing file descriptors before invoking a child process.
- Security best practices involve using functions like
fcntl
to set the FD_CLOEXEC flag on file descriptors. - Recommended tools and frameworks include static analysis tools to detect open file descriptors and frameworks that manage process spawning securely.
Corgea can automatically detect and fix Exposure of File Descriptor to Unintended Control Sphere ('File Descriptor Leak') in your codebase. Try Corgea free today.
Technical Details
Likelihood of Exploit: Not specified
Affected Languages: C, Not Language-Specific
Affected Technologies: Not specified
Vulnerable Code Example
C Example
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
int main() {
// Open a sensitive file
int fd = open("sensitive_data.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
// Vulnerable: The file descriptor 'fd' is inherited by the child process
// This can lead to unauthorized access to 'sensitive_data.txt' by the child process
if (fork() == 0) {
// Child process
execl("/bin/ls", "ls", NULL); // This child process will inherit 'fd' and could misuse it
_exit(1); // Use _exit to ensure no cleanup is done by the child
}
// Parent process
wait(NULL);
close(fd); // Correctly close the file descriptor in the parent process
return 0;
}
How to fix Exposure of File Descriptor to Unintended Control Sphere ('File Descriptor Leak')?
To fix this vulnerability, ensure that sensitive file descriptors are not inherited by child processes unless explicitly intended. This can be accomplished by setting the FD_CLOEXEC
flag on the file descriptor, which automatically closes the file descriptor during an exec
function call. This prevents unintended access to the file descriptor by spawned child processes.
Using the fcntl
function, we can set this flag immediately after opening the file. This is a common security practice to prevent file descriptor leaks.
Fixed Code Example
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
int main() {
// Open a sensitive file
int fd = open("sensitive_data.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
// Fix: Set the FD_CLOEXEC flag to prevent child processes from inheriting the file descriptor
int flags = fcntl(fd, F_GETFD);
if (flags == -1) {
perror("fcntl");
close(fd);
return 1;
}
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
perror("fcntl");
close(fd);
return 1;
}
// Correctly manage the file descriptor inheritance
if (fork() == 0) {
// Child process
execl("/bin/ls", "ls", NULL); // This child process will not inherit 'fd'
_exit(1); // Use _exit to ensure no cleanup is done by the child
}
// Parent process
wait(NULL);
close(fd); // Correctly close the file descriptor in the parent process
return 0;
}
By setting FD_CLOEXEC
, the file descriptor is automatically closed when a new program is executed by the child process, thus preventing any unauthorized access to sensitive files. This is a critical security measure when handling file descriptors in C programming. Additionally, using _exit
in the child process ensures that no cleanup (like closing file descriptors) is performed, which is important for security and correctness.