Vulnerability DatabaseCVE-2026-112907

CVE-2026-112907: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-112907 is an improper locking vulnerability (CWE-667) in the Python filelock library affecting soft lock implementations on Windows. A local attacker with read access to a soft lock's marker file can take a Windows opportunistic lock (oplock) on it and leave the break unanswered, causing SoftFileLock.acquire() to block indefinitely past its configured timeout. Affected versions are filelock 3.22.0 through 4.2.0 on Windows; the patched version is 4.2.1. It carries a CVSS v3.1 score of 2.5 (Low) (GitHub Advisory).

Technical details

The root cause is that soft lock implementations (SoftFileLock, MarkerSoftFileLock, SoftFileLease, their async variants, and FileLock after an ENOSYS fallback) read and manipulate their marker file by path using os.open, os.rename, and os.unlink. On Windows, these calls internally invoke CreateFileW, which waits for any outstanding oplock break acknowledgment before proceeding — a behavior not present on Linux. A local account with read access to the marker directory (via inherited ACL) can open the marker with a read handle and request a Level 1 oplock via DeviceIoControl(FSCTL_REQUEST_OPLOCK_LEVEL_1), then never acknowledge the break. Because _check_give_up (which enforces timeout, blocking=False, and cancel_check) is only consulted between retry attempts — not during the blocking os.open call — the timeout is bypassed entirely. The vulnerability was introduced in commit e35c3af (PR #476, 2026-02-13) with the addition of stale lock detection, first released in version 3.22.0 (GitHub Advisory).

Impact

Exploitation causes a partial availability impact: any thread calling SoftFileLock.acquire() that encounters a marker under an oplock will block for approximately 10 seconds per attempt (in two-account test runs) regardless of the configured timeout, blocking=False, or cancel_check. When using AsyncSoftFileLock(run_in_executor=False), the wait occurs on the event loop thread, stalling all tasks in the process. If the marker is stale, it cannot be broken or removed while the oplock is held, preventing any process from acquiring the lock until the oplock holder closes its handle. Mutual exclusion is not compromised, and no data other than the marker's content (process ID and hostname) is exposed (GitHub Advisory).

Exploitability

No public exploit code or in-the-wild exploitation has been reported. The vulnerability requires a local account with read access to the marker file's directory, and the oplock can only be granted when no other handle is open on the marker (e.g., after a holder process dies or closes its descriptor), making exploitation opportunistic and of high attack complexity. The CVE was discovered internally by the filelock maintainers during a review of a separate finding reported by Anthropic's OSS Scanner on 15 October 2026; it is not listed in CISA's Known Exploited Vulnerabilities catalog. No EPSS score is currently available (GitHub Advisory).

Exploitation steps

  1. Reconnaissance: Identify a Windows host where the target user runs a Python application using filelock versions 3.22.0–4.2.0 with soft lock classes (SoftFileLock, FileLock with ENOSYS fallback, etc.), and locate the marker file path (the .lock file).
  2. Gain read access: Obtain a local account on the same host that has read access to the lock marker directory via inherited ACL entries (e.g., standard Users group membership with (OI)(CI)(M) on the directory).
  3. Wait for an unheld marker: Monitor for a window when no process holds an open handle on the marker — for example, after the legitimate lock holder dies, closes its descriptor, or between lock acquisition cycles.
  4. Request a Level 1 oplock: Using CreateFileW with GENERIC_READ and FILE_FLAG_OVERLAPPED, open the marker file, then issue DeviceIoControl(FSCTL_REQUEST_OPLOCK_LEVEL_1) to request an opportunistic lock. Keep the thread alive and never acknowledge any break notification.
  5. Trigger the victim's acquire: Wait for the legitimate lock user to call SoftFileLock.acquire(). Their os.open(marker, O_RDONLY) inside _read_lock_file will block waiting for the oplock break acknowledgment, bypassing any configured timeout.
  6. Sustain the denial: Maintain the oplock handle open to prevent stale marker cleanup (os.rename/os.unlink also block under the oplock), keeping the lock permanently unavailable to the victim process (GitHub Advisory).

Indicators of compromise

  • Process Behavior: Lock-using threads or async event loops hanging for 10+ seconds per acquire() attempt on Windows, far exceeding the configured timeout value.
  • Logs: Application-level timeout errors (filelock.Timeout) raised significantly later than the configured timeout (e.g., Timeout after 10.02 s when timeout=1 was set).
  • File System: Stale .lock marker files persisting on disk despite no active holder process, and failing to be renamed or deleted by the lock library's stale-break logic.
  • Windows Event/Handle Monitoring: Unexpected read handles on .lock marker files held by a different local user account; DeviceIoControl calls with FSCTL_REQUEST_OPLOCK_LEVEL_1 (0x00090000) against lock marker files from a non-owner account (GitHub Advisory).

Mitigation and workarounds

Upgrade filelock to version 4.2.1, which contains the fix from PR #835. If immediate upgrade is not possible, apply the following workarounds: (1) Store soft-lock markers in a directory whose ACL grants other local accounts no access to new files — use a directory inside the user profile, or remove inheritance and restrict access with icacls /inheritance:r /grant:r "OWNER:(OI)(CI)F" "SYSTEM:(OI)(CI)F" "Administrators:(OI)(CI)F"; note that the mode parameter does not enforce this on Windows. (2) If using AsyncSoftFileLock, use the default executor (run_in_executor=True) rather than run_in_executor=False, so that only a worker thread blocks rather than the event loop. No timeout, blocking, or cancel_check value can bound the wait in unpatched versions (GitHub Advisory).

Community reactions

The vulnerability was discovered by the filelock maintainers themselves during an internal review of PR #835, which was addressing a separate Linux lease finding (GHSA-7hmp-gf99-57hx) reported by Anthropic's OSS Scanner. The maintainers noted that the scanner's 36-finding report did not include this defect, and it was identified independently during their review process. No notable external researcher commentary or media coverage has been observed (GitHub Advisory).

Additional resources


Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-mpqx-q82w-9x46HIGH7.5
  • Python logoPython
  • graphql-core
NoYesOct 25, 2026
GHSA-4gm2-62xx-xwvxMEDIUM5.3
  • Python logoPython
  • aynops
NoYesOct 25, 2026
GHSA-jm75-qwf5-vg52MEDIUMN/A
  • Python logoPython
  • exmergo-dex-core
NoYesOct 25, 2026
GHSA-f3jf-cv9h-7c3gHIGHN/A
  • Python logoPython
  • exmergo-dex-core
NoYesOct 25, 2026
GHSA-28xv-9wpg-c42rHIGHN/A
  • Python logoPython
  • exmergo-dex-core
NoYesOct 25, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Additional Wiz resources

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management