CVE-2026-112941:
Python 취약성 분석 및 완화
개요
CVE-2026-112941 is a Time-of-Check Time-of-Use (TOCTOU) race condition vulnerability in the filelock Python library (maintained by tox-dev) affecting SoftReadWriteLock and AsyncSoftReadWriteLock. Versions 4.1.0 through 4.2.0 are vulnerable; the issue was introduced in version 4.1.0 and fixed in 4.2.1. The vulnerability was reported by Anthropic's OSS Scanner on October 15, 2026, and publicly disclosed on October 17, 2026. It carries a CVSS v3.1 base score of 3.3 (Low) (GitHub Advisory, Red Hat CVE).
기술적 세부 사항
The root cause is a CWE-367 (Time-of-Check Time-of-Use) race condition in OsFiles.prepare(), which checks once per lock object (using a _prepared boolean shortcut introduced in commit 367b111) that .rw, .rw/gen, and .rw/holders are real directories and not symbolic links. However, every subsequent record operation (create, link, replace, unlink, listdir) resolves the full path again by name, and O_NOFOLLOW only protects the final path component — not intermediate directory components. A local attacker who can write to the directory containing the lock (e.g., a shared 0777 directory without the sticky bit, or a sticky directory like /tmp where the attacker created .rw first) can rename the legitimate .rw tree aside and plant a replacement tree whose gen or holders subdirectory is a symbolic link pointing to an arbitrary directory writable by the lock user. Because the live lock object never re-runs the directory check, subsequent lock acquisitions by the victim process transparently write lock records (epoch files, generation records, and HEAD renames) into the attacker-chosen target directory. There is no timing race to win — the swap occurs between two acquisitions of a long-lived lock object (GitHub Advisory, Fix PR #842).
영향
A local low-privileged attacker can cause the lock user's process to write filelock-controlled files (epoch records, generation records, and a renamed HEAD file) into any directory the lock user can write — including private 0700 directories the attacker cannot directly access. The bytes written are filelock's own protocol records (not attacker-chosen content), but the effect is destructive: for example, the attacker can corrupt a git repository's .git/HEAD, rendering it unusable (git status reports fatal: not a git repository). Additionally, the sweep mechanism can delete files with 32-hex-digit names in the target directory, and generation log compaction can delete 20-digit filenames. There is no confidentiality impact and no direct availability impact on the lock itself, but integrity of targeted files is compromised (GitHub Advisory).
악용 가능성
There is no public proof-of-concept exploit and no evidence of in-the-wild exploitation as of the disclosure date (Feedly). The EPSS score is 0.0, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities catalog. Exploitation requires a local account on the same host and write access to the directory containing the lock path (or the ability to create .rw before the lock user in a sticky directory). The attack has no timing race — the swap simply needs to occur between two acquisitions of a long-lived lock object, making it straightforward for a patient local attacker (GitHub Advisory).
착취 단계
- Identify a target: Locate a system where a victim process uses
SoftReadWriteLockorAsyncSoftReadWriteLock(filelock 4.1.0–4.2.0) with a lock path in a directory the attacker can write to (e.g., a0777non-sticky shared directory like/srv/shared, or a sticky/tmpwhere the attacker can create.rwfirst). - Wait for first acquisition: Allow the victim's long-lived lock object to complete its first
write_lock()acquisition, which createsapp.lock.rw(owned by the victim, mode0700) and sets_prepared = True. - Swap the lock tree (non-sticky parent): As the attacker, rename the victim's
app.lock.rwaside (rename(app.lock.rw, app.lock.rw.aside)), then create a newapp.lock.rwdirectory with a world-writableholders/subdirectory and agenentry that is a symbolic link pointing to the target directory (e.g.,/home/victim/project/.git). - Trigger second acquisition: Wait for the victim's process to acquire the lock a second time. Because
_preparedisTrue,prepare()returns immediately without re-checking the tree. - Observe file writes into target: The victim's lock operations now traverse the symlink:
_incarnation()createsepochin the target,commit()creates generation records and renames a record overHEADin the target directory — all with the victim's privileges, even though the attacker cannot directly access the target directory. - Verify impact: The target directory (e.g.,
.git) now contains filelock protocol files, andHEADhas been overwritten with a filelock record, breaking the git repository (GitHub Advisory).
타협의 징후
- File System: Unexpected files named
epoch, 20-digit numeric names (e.g.,00000000000000000001), or.commit-*temporary files appearing in directories unrelated to the lock path (e.g., inside a.gitdirectory or other application data directories). - File System: A file named
HEADin a git repository or other sensitive directory whose content has been replaced with a filelock record (e.g., content matching\nfilelock-rw/1\ngeneration=N\n). - File System: Presence of a
<lockname>.rw.asidedirectory alongside the expected lock tree, indicating the original lock tree was renamed by an attacker. - File System: A
<lockname>.rw/genentry that is a symbolic link (detectable vials -laorlstat) rather than a real directory, pointing to a sensitive directory. - Process: Unexpected file creation or rename operations by the lock-user process in directories outside the expected lock tree, observable via
auditdorinotifywaitmonitoring on sensitive directories.
완화 및 해결 방법
Upgrade filelock to version 4.2.1 or later, which fixes the vulnerability by opening .rw, gen, and holders via directory file descriptors (O_NOFOLLOW) for every record operation on platforms supporting dir_fd, and by repeating ownership checks whenever a replaced tree is detected (filelock 4.2.1 Release, Fix PR #842). If immediate upgrade is not possible, apply these workarounds: keep the lock path in a directory owned exclusively by the locking account (or root) with no group or other write bits; avoid placing SoftReadWriteLock paths in world-writable directories like /tmp unless the locking account creates .rw first with mode 0700; and prefer creating a fresh lock object per unit of work (rather than a long-lived singleton) so that prepare() re-runs its directory check on each use (GitHub Advisory).
커뮤니티 반응
The vulnerability was reported privately by Anthropic's OSS Scanner (automated analysis) on October 15, 2026, under internal identifier ANT-2026-WXXRI4M4, and the maintainer (gaborbernat) opened a fix PR within hours of receiving the report. The advisory notes that Anthropic's scanner rated the issue as high severity, while the maintainers scored it as low (CVSS 3.3) based on the limited integrity impact (filelock's own records, not attacker-chosen bytes). No significant broader community or media reactions have been identified beyond the GitHub advisory and Red Hat tracking (GitHub Advisory, Red Hat CVE).
추가 자료
리눅스 배포판 수정 현황
주요 리눅스 배포판과 그 릴리스 전반에 걸친 가용성을 수정하세요.
bookworm
python-filelock
sid
python-filelock
trixie
python-filelock
bionic (esm-apps)
python-filelock
devel
python-filelock
focal (esm-apps)
python-filelock
jammy
python-filelock
jammy (esm-apps)
python-filelock
noble
python-filelock
noble (esm-apps)
python-filelock
resolute
python-filelock
근원: 이 보고서는 AI를 사용하여 생성되었습니다.
관련 Python 취약점:
무료 취약성 평가
클라우드 보안 태세를 벤치마킹합니다
9개의 보안 도메인에서 클라우드 보안 관행을 평가하여 위험 수준을 벤치마킹하고 방어의 허점을 식별합니다.
추가 Wiz 리소스
맞춤형 데모 받기
맞춤형 데모 신청하기
"내가 본 최고의 사용자 경험은 클라우드 워크로드에 대한 완전한 가시성을 제공합니다."
"Wiz는 클라우드 환경에서 무슨 일이 일어나고 있는지 볼 수 있는 단일 창을 제공합니다."
"우리는 Wiz가 무언가를 중요한 것으로 식별하면 실제로 중요하다는 것을 알고 있습니다."