
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-112938 is a race condition enabling symbolic link following in the Python filelock library's StrictSoftFileLock and AsyncStrictSoftFileLock classes. A local attacker with write access to a shared directory can exploit a TOCTOU (time-of-check to time-of-use) flaw to redirect lock claim file creation into an attacker-chosen directory. The vulnerability affects filelock versions >= 3.30.0 and <= 4.2.0 (pip package, vendor: tox-dev), and was reported on October 15, 2026, with a fix published October 17, 2026. It carries a CVSS v3.1 base score of 5.8 (Medium) (GitHub Advisory, Security Advisory).
The root cause is CWE-363 (Race Condition Enabling Link Following): StrictSoftFileLock._acquire checks <path>.filelock with a single lstat call, then subsequently accesses <path>.filelock/claims by pathname for all subsequent operations (mkdir, scan, publish, link, unlink). While _open_directory passes O_NOFOLLOW, this flag only protects the final claims path component — the kernel will still follow a symbolic link in any earlier component (i.e., .filelock itself). An attacker exploits this window by atomically swapping .filelock for a symlink pointing to a target directory using renameat2(RENAME_EXCHANGE) in a tight loop; when the swap lands between the lstat and the subsequent mkdir, the lock user's process creates claims/ and claim files inside the attacker-chosen target directory with the lock user's privileges. Additionally, the claims property and force_break() resolve the path with no check at all, enabling two no-race attack variants. The vulnerability was introduced with commit 650c17c (PR #659, 2026-07-14) and first released in version 3.30.0 (GitHub Advisory, Security Advisory).
Successful exploitation allows a local attacker to cause the lock user's process (potentially running as root) to create a claims directory and claim files with the lock user's privileges inside an attacker-chosen directory. The primary availability impact is high: if the symlink targets another strict lock's .filelock directory, stranded claim files cause that lock to time out for every process until an operator manually force-breaks each one, effectively denying the lock to all users. Confidentiality impact is low — through the claims property, an attacker can learn one file name per planted link from a directory only the lock user can list. Integrity impact is also low — the lock user's process creates directories and fixed-format claim files in the attacker-chosen location, but does not overwrite or truncate existing data. The force_break() variant can additionally place two processes simultaneously inside a different strict lock's critical section without either being notified (GitHub Advisory, Security Advisory).
No public proof-of-concept exploit code or in-the-wild exploitation has been reported. The vulnerability was discovered by Anthropic's OSS Scanner (automated analysis) and reported on October 15, 2026. Exploitation requires a local unprivileged account on the same host and high attack complexity — the renameat2(RENAME_EXCHANGE) swap must land within a narrow window between two system calls, though the attacker's loop approach succeeded in 1–31 attempts (about 1.5 seconds) in testing. The CVE status is listed as "Reserved" and no EPSS score or CISA KEV catalog entry is available at this time (GitHub Advisory, Security Advisory).
filelock >= 3.30.0 and <= 4.2.0 is installed and a privileged process (e.g., root or a service account) uses StrictSoftFileLock on a path in a shared, non-sticky directory (e.g., /dev/shm/ or a world-writable project directory)..filelock directory or a private directory): os.symlink('/home/victim/private', '/dev/shm/work.lock.decoy').renameat2(RENAME_EXCHANGE), so the name alternates between the real directory and the symlink with every syscall iteration.lstat check (which sees the real directory) and the subsequent mkdir .filelock/claims call (which now follows the symlink into the target directory). This typically succeeds within 1–31 lock acquisition attempts.claims/ and claim files (intent-v1-*.claim, held-v1-*.claim) inside the attacker-chosen target directory with the lock user's privileges. If the target is another strict lock's .filelock directory, that lock becomes permanently timed out until an operator manually force-breaks each stranded claim..filelock/claims directly (no race needed) to trigger SoftFileLockProtocolError that leaks a file name from the lock user's private directory, or plant a symlink at the lock path to abuse force_break() and break a live lock's critical section exclusion (GitHub Advisory, Security Advisory).claims/ directory (owned by the lock user, mode 0755) appearing inside directories unrelated to the lock's intended path (e.g., inside another lock's .filelock directory or a private directory).intent-v1-*.claim, held-v1-*.claim, or .held-v1-*.claim.private-v1-*.tmp files in unexpected locations outside the intended lock directory..decoy or similar) appearing alongside the lock's .filelock coordination directory in a shared directory.SoftFileLockProtocolError or FileNotFoundError exceptions in application logs referencing the lock path, indicating failed acquisition attempts during the swap loop.Timeout errors from StrictSoftFileLock on a lock that no process is actively holding, suggesting stranded claim files are blocking acquisition.renameat2 syscalls in a tight loop on the .filelock directory name (observable via strace or auditd syscall monitoring) (GitHub Advisory, Security Advisory).Upgrade filelock to version 4.2.1 or later, which fixes the vulnerability by opening .filelock with O_NOFOLLOW and accessing claims relative to that file descriptor (using dir_fd/openat), so a symlink swapped in at either level fails the operation instead of redirecting it. The fix also sets the sticky bit on both .filelock and claims directories and applies the lock's mode to them. If immediate upgrade is not possible, apply these workarounds: keep strict locks in a directory no other user can write; in sticky shared directories (e.g., /tmp), pre-create .filelock as the service user before any other account can; do not run the blind recovery loop from docs/tutorials.rst on locks in shared directories without first verifying claim ownership as described in docs/how-to.rst; and treat unexpected SoftFileLockProtocolError quoting an unknown claim name as a potential sign of exploitation (Security Advisory, Release 4.2.1).
The vulnerability was discovered by Anthropic's OSS Scanner (automated analysis) and reported to the maintainers on October 15, 2026. The maintainer (gaborbernat) opened a fix PR within approximately two hours of receiving the report and published the patched release 4.2.1 on October 17, 2026, demonstrating a rapid response. The advisory notes that this vulnerability shares only the bug class with a prior related issue (GHSA-j8f7-rjxc-mr56), but differs in that the symlink sits one path component above the final one and is swapped in after the check rather than resting statically. No significant broader community or media reactions have been identified beyond the GitHub advisory and associated tooling coverage (GitHub Advisory, Security Advisory).
Fix availability across major Linux distributions and their releases.
bookworm
python-filelock
sid
python-filelock: 4.2.2-1
trixie
python-filelock
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."