Race Conditions and TOCTOU bugs
Time-of-Check to Time-of-Use (TOCTOU) vulnerabilities are a class of race condition bugs that occur when there's a time gap between checking a resource and using it, during which the resource can be modified by an attacker.
Understanding the Problem
TOCTOU vulnerabilities typically follow this pattern:
- Check - Application verifies a condition (file permissions, user rights, etc.)
- Time Gap - Brief period where attacker can modify the resource
- Use - Application acts based on the earlier check, now potentially invalid
Classic Example: File Operations
// VULNERABLE CODE
if (access("/tmp/file", W_OK) == 0) { // Check: Can we write?
// TIME GAP - Attacker can replace /tmp/file with symlink
FILE *fp = fopen("/tmp/file", "w"); // Use: Write to file
fprintf(fp, "sensitive data");
fclose(fp);
}
Between the access() check and fopen() use, an attacker could replace the file with a symbolic link pointing to a sensitive system file.
Mitigation Strategies
- Atomic operations - Use operations that check and act in one step
- File descriptors - Keep file handles open to maintain consistency
- Proper locking - Use filesystem locks or application-level synchronization
- Avoid privileged operations - Drop privileges early when possible
Secure Alternative
// SECURE CODE
int fd = open("/tmp/file", O_WRONLY | O_CREAT | O_EXCL, 0600);
if (fd != -1) {
// File was created atomically, safe to use
write(fd, "sensitive data", 14);
close(fd);
}
Web Application Context
TOCTOU bugs also appear in web applications, particularly around:
- Session validation and usage
- Database constraint checks
- File upload validation
- Rate limiting implementations
The key to preventing TOCTOU vulnerabilities is to minimize or eliminate the time gap between check and use operations.