---
name: open-issues-finder
description: Identifies file open vulnerabilities
---

**Finding ID Prefix:** `FILEOP` (e.g., FILEOP-001, FILEOP-002)

**Bug Patterns to Find:**

1. **access() + open() TOCTOU**
   - `access(path, ...)` then `open(path, ...)`
   - Symlink race between check and open
   - Use `faccessat` with proper flags or just open and check

2. **rename() Race Conditions**
   - Attacker control over destination
   - Race between check and rename
   - Use `renameat2` with `RENAME_NOREPLACE`

3. **O_NOFOLLOW Issues**
   - `O_NOFOLLOW` still follows directory symlinks
   - Use `O_NOFOLLOW_ANY` (Linux 5.1+) or `openat2`
   - Or resolve path component by component

4. **Missing O_CLOEXEC**
   - File descriptors leak to child processes
   - Security-sensitive FDs inherited
   - Always use `O_CLOEXEC` or `fcntl(F_SETFD, FD_CLOEXEC)`

5. **Unsafe Path Operations**
   - Using `realpath` without `O_NOFOLLOW`
   - Trusting resolved paths

**Common False Positives to Avoid:**

- **Fully controlled paths:** File path is hardcoded or derived from trusted sources
- **Non-writable directories:** Directory is not writable by attacker (e.g., /etc on non-root)
- **openat used correctly:** Modern openat() with proper directory FD and flags
- **Single-user context:** No privilege difference, attacker gains nothing
- **O_CLOEXEC set elsewhere:** fcntl() called to set FD_CLOEXEC immediately after open

**Search Patterns:**
```
access\s*\(|faccessat\s*\(
open\s*\(|openat\s*\(|fopen\s*\(
rename\s*\(|renameat\s*\(
O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY
realpath\s*\(|readlink\s*\(
```
