Skip to content

deps: bump multidict from 6.8.0 to 6.9.1 - #161

Open
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/uv/multidict-6.9.1
Open

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/uv/multidict-6.9.1

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 20, 2026 •

Copy link
Copy Markdown

Bumps multidict from 6.8.0 to 6.9.1.

Release notes

Sourced from multidict's releases.

6.9.1

Bug fixes

  • Fixed the C extension reading freed memory on free-threaded builds when a list handed to :py:meth:~multidict.MultiDict.update, :py:meth:~multidict.MultiDict.extend, :py:meth:~multidict.MultiDict.merge or the :py:class:~multidict.MultiDict and :py:class:~multidict.CIMultiDict constructors, a [key, value] item inside any iterable handed to them, or a list tested with in against :py:meth:~multidict.MultiDict.items, is changed by another thread; a call that catches the list shrinking under it now raises :py:exc:RuntimeError -- by :user:rodrigobnogueira.

    Related issues and pull requests on GitHub: #1437.

  • Fixed a data race on the free-threaded build where a retired hash table's reader count used relaxed atomics, letting a lock-free get()/getone()/ __getitem__() read race a concurrent free of that table. The reader-exit decrement and the drain's free check now use release/acquire ordering instead -- by :user:asvetlov.

    Related issues and pull requests on GitHub: #1481.

  • Fixed a free-threaded build bug where two threads calling update(), merge(), or __setitem__() on the same key at the same time could lose the key entirely instead of just racing on which value wins. A decref of the replaced value could transiently suspend the writer's critical section, letting a second writer for the same key observe the first writer's in-progress entry as absent and, once both settled, mistake it for a stale duplicate and delete it. Every such decref is now deferred until the writer has released its critical section, so the window can no longer open. setdefault() had an unrelated instance of the same blind spot (it could insert a duplicate rather than recognizing an in-flight key), fixed alongside it -- by :user:asvetlov.

    Related issues and pull requests on GitHub: #1483.

  • Fixed a free-threaded build bug where getall() and the items()/ keys()/values() equality path could raise KeyError or report a present, never-deleted key as missing. A concurrent update()/extend()/ __setitem__() call can have its critical section transiently suspended (a decref triggering a blocking allocator call) while an entry is marked as part of its own bookkeeping; a reader landing in that window used to treat the mark as "not found" instead of "still there, in flight" -- by :user:asvetlov.

    Related issues and pull requests on GitHub:

... (truncated)

Changelog

Sourced from multidict's changelog.

6.9.1

(2026-09-21)

Bug fixes

  • Fixed the C extension reading freed memory on free-threaded builds when a list handed to :py:meth:~multidict.MultiDict.update, :py:meth:~multidict.MultiDict.extend, :py:meth:~multidict.MultiDict.merge or the :py:class:~multidict.MultiDict and :py:class:~multidict.CIMultiDict constructors, a [key, value] item inside any iterable handed to them, or a list tested with in against :py:meth:~multidict.MultiDict.items, is changed by another thread; a call that catches the list shrinking under it now raises :py:exc:RuntimeError -- by :user:rodrigobnogueira.

    Related issues and pull requests on GitHub: :issue:1437.

  • Fixed a data race on the free-threaded build where a retired hash table's reader count used relaxed atomics, letting a lock-free get()/getone()/ __getitem__() read race a concurrent free of that table. The reader-exit decrement and the drain's free check now use release/acquire ordering instead -- by :user:asvetlov.

    Related issues and pull requests on GitHub: :issue:1481.

  • Fixed a free-threaded build bug where two threads calling update(), merge(), or __setitem__() on the same key at the same time could lose the key entirely instead of just racing on which value wins. A decref of the replaced value could transiently suspend the writer's critical section, letting a second writer for the same key observe the first writer's in-progress entry as absent and, once both settled, mistake it for a stale duplicate and delete it. Every such decref is now deferred until the writer has released its critical section, so the window can no longer open. setdefault() had an unrelated instance of the same blind spot (it could insert a duplicate rather than recognizing an in-flight key), fixed alongside it -- by :user:asvetlov.

    Related issues and pull requests on GitHub: :issue:1483.

  • Fixed a free-threaded build bug where getall() and the items()/ keys()/values() equality path could raise KeyError or report a present, never-deleted key as missing. A concurrent update()/extend()/ __setitem__() call can have its critical section transiently suspended (a decref triggering a blocking allocator call) while an entry is marked as

... (truncated)

Commits
  • 0a1770c Release 6.9.1 (#1504)
  • d220522 Upload release assets one at a time to avoid the secondary rate limit (#1503)
  • 30cd596 Stop a GIL-releasing del from segfaulting the standard C extension build ...
  • d1c331a Recheck the reader gate after taking the retired list (#1502)
  • b37f07c Allocate deferred decrefs in fixed-size blocks (#1501)
  • 563f667 Run CodSpeed benchmarks on Python 3.14 and loop the smallest ones (#1498)
  • 157c87c Cancel superseded CI runs on pull requests (#1500)
  • d43adfe Drop -I from the ASan test command so PYTHONMALLOC takes effect (#1499)
  • 2a68472 Stop items() iteration from reading a freed entry in CIMultiDict (#1496)
  • cd528d6 Rename GHSA-54p9-h82j-f925 changelog fragment to the merged commit (#1495)
  • Additional commits viewable in compare view

@dependabot @github

dependabot Bot commented on behalf of github Oct 20, 2026

Copy link
Copy Markdown
Author

Labels

The following labels could not be found: dependencies. Please create it before Dependabot can add it to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Dependency Security Audit

Scanned: pyproject.toml dependencies + dev group, resolved at Python 3.10 (the current resolution, and the lowest versions the published specs permit under each pydantic major)

❌ 6 fixable HIGH/CRITICAL advisories -- blocking this build.

Severity Count
‼️ CRITICAL 1
🔴 HIGH 5
🔶 MEDIUM 18
⚪ LOW 5
❔ UNKNOWN 28
Severity Package Installed Fixed in Advisory
‼️ CRITICAL uv 0.12.17 0.13.4 GHSA-hq85-5cpj-mr62
🔴 HIGH aiohttp 3.14.3 3.14.4 CVE-2026-111064
🔴 HIGH aiohttp 3.14.3 3.14.4 CVE-2026-111066
🔴 HIGH aiohttp 3.14.3 3.14.4 GHSA-2g87-pp6c-29x5
🔴 HIGH dnspython 2.8.0 2.9.0 CVE-2026-114605
🔴 HIGH filelock 4.1.0 4.2.1 CVE-2026-112940
🔶 MEDIUM aiohttp 3.14.3 3.14.4 CVE-2026-111063
🔶 MEDIUM aiohttp 3.14.3 3.14.4 CVE-2026-111065
🔶 MEDIUM aiohttp 3.14.3 3.14.4 CVE-2026-111748
🔶 MEDIUM aiohttp 3.14.3 3.14.4 CVE-2026-111750
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112906
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112908
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112909
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112910
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112911
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112914
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112915
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112934
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112935
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112937
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112938
🔶 MEDIUM filelock 4.1.0 4.2.1 CVE-2026-112939
🔶 MEDIUM uv 0.12.17 0.12.18 CVE-2026-104843
🔶 MEDIUM werkzeug 3.1.8 3.1.9 CVE-2026-102598
⚪ LOW aiohttp 3.14.3 3.14.4 CVE-2026-111749
⚪ LOW filelock 4.1.0 4.2.1 CVE-2026-112907
⚪ LOW filelock 4.1.0 4.2.1 CVE-2026-112912
⚪ LOW filelock 4.1.0 4.2.1 CVE-2026-112913
⚪ LOW filelock 4.1.0 4.2.1 CVE-2026-112941
❔ UNKNOWN aiohttp 3.14.3 3.14.4 CVE-2026-111063 (GHSA-494j-54xm-rwp3)
❔ UNKNOWN aiohttp 3.14.3 3.14.4 CVE-2026-111064 (GHSA-5wr8-gcqf-gqf3)
❔ UNKNOWN aiohttp 3.14.3 3.14.4 CVE-2026-111065 (GHSA-6cjc-53gc-5rqm)
❔ UNKNOWN aiohttp 3.14.3 3.14.4 CVE-2026-111066 (GHSA-9xw5-w5jj-pvcg)
❔ UNKNOWN aiohttp 3.14.3 3.14.4 CVE-2026-111748 (GHSA-f9xw-jh8m-3mwq)
❔ UNKNOWN aiohttp 3.14.3 3.14.4 CVE-2026-111749 (GHSA-gx76-c99x-2c96)
❔ UNKNOWN aiohttp 3.14.3 3.14.4 CVE-2026-111750 (GHSA-pqxq-w44r-73xw)
❔ UNKNOWN dnspython 2.8.0 2.9.0 CVE-2026-114605 (GHSA-45c3-73f7-pv4m)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112906 (GHSA-2g95-wg33-c5x2)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112907 (GHSA-567q-5qvw-pf92)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112908 (GHSA-6627-m3xw-93mp)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112909 (GHSA-69hj-f68j-2879)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112910 (GHSA-8mx5-7m5m-r77g)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112911 (GHSA-9c4x-gm8v-wgc4)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112912 (GHSA-9j6q-wvj5-jgjg)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112913 (GHSA-9vhv-jxww-xfm5)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112914 (GHSA-crv4-6mhj-j5jh)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112915 (GHSA-cwqr-hh33-gh44)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112934 (GHSA-fj95-fr6c-h845)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112935 (GHSA-fq56-3cx3-fjxp)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112937 (GHSA-jqc4-5cvw-7w85)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112938 (GHSA-m462-7rxw-wvpg)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112939 (GHSA-rfpc-qcw5-3pc4)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112940 (GHSA-v4x8-3wr5-3wq8)
❔ UNKNOWN filelock 4.1.0 4.2.1 CVE-2026-112941 (GHSA-wfhq-q4j2-c37m)
❔ UNKNOWN uv 0.12.17 0.12.18 PYSEC-2026-4305 (CVE-2026-104843, GHSA-2cv4-cqwr-gwf7)
❔ UNKNOWN uv 0.12.17 0.13.4 PYSEC-2026-4321 (GHSA-hq85-5cpj-mr62)
❔ UNKNOWN werkzeug 3.1.8 3.1.9 PYSEC-2026-4312 (CVE-2026-102598, GHSA-g6x2-hccm-hh4m)
Advisory details

CRITICAL -- GHSA-hq85-5cpj-mr62 (uv 0.12.17)

Found by: trivy:dev-ceiling

uv's bundled CA store trusts an emSign root whose intermediate CA keys are compromised

HIGH -- CVE-2026-111064 (aiohttp 3.14.3)

Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2

aiohttp: aiohttp: Denial of Service via missing initial request timeout

HIGH -- CVE-2026-111066 (aiohttp 3.14.3)

Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2

aiohttp: aiohttp: Denial of Service via file descriptor exhaustion in multipart request processing

HIGH -- GHSA-2g87-pp6c-29x5 (aiohttp 3.14.3)

Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2, trivy:runtime-floor, trivy:runtime-floor-pydantic-v2

aiohttp: Multiple instances of excessive or unbounded memory/CPU use

HIGH -- CVE-2026-114605 (dnspython 2.8.0)

Found by: trivy:dev-ceiling, trivy:runtime-ceiling, trivy:runtime-floor, trivy:runtime-floor-pydantic-v2

dnspython: dnspython: Denial of Service via excessive DNS compression pointer traversal

HIGH -- CVE-2026-112940 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Arbitrary file overwrite via insecure database file reopening

MEDIUM -- CVE-2026-111063 (aiohttp 3.14.3)

Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2

aiohttp: aiohttp: Information disclosure via unenforced Secure attribute on shared cookies

MEDIUM -- CVE-2026-111065 (aiohttp 3.14.3)

Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2

aiohttp: aiohttp: Denial of Service via Max-Age processing overflow

MEDIUM -- CVE-2026-111748 (aiohttp 3.14.3)

Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2

aiohttp: aiohttp: Security control bypass via request scheme spoofing

MEDIUM -- CVE-2026-111750 (aiohttp 3.14.3)

Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2

aiohttp: aiohttp: HTTP request smuggling via ambiguous request framing

MEDIUM -- CVE-2026-112906 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Mutual exclusion bypass via improper stale lock removal

MEDIUM -- CVE-2026-112908 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: StrictSoftFileLock creates its claim directories without the lock mode, so another local user with a write bit on them can end a live hold

MEDIUM -- CVE-2026-112909 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: arbitrary file truncation via lock path replacement

MEDIUM -- CVE-2026-112910 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: WindowsFileLock ignores mode: a 0o600 lock file and the ReadWriteLock database inherit the directory ACL

MEDIUM -- CVE-2026-112911 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Lock bypass via pre-created shared protocol directory

MEDIUM -- CVE-2026-112914 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Unauthorized file exposure via symbolic link manipulation in SoftFileLock

MEDIUM -- CVE-2026-112915 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Denial of Service via crafted SQLite lock database

MEDIUM -- CVE-2026-112934 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Denial of Service via insecure holder record refresh

MEDIUM -- CVE-2026-112935 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Unauthorized concurrent access via stale lock cleanup race condition

MEDIUM -- CVE-2026-112937 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock is a platform-independent file lock for Python. From 4.1.0 un ...

MEDIUM -- CVE-2026-112938 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: StrictSoftFileLock follows a symbolic link swapped in at <path>.filelock and creates claim files in a directory another local user chooses

MEDIUM -- CVE-2026-112939 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Unauthorized lock acquisition via forged process identifier in SoftFileLock

MEDIUM -- CVE-2026-104843 (uv 0.12.17)

Found by: trivy:dev-ceiling

uv: uv: Arbitrary code execution via malicious package extraction on Windows

MEDIUM -- CVE-2026-102598 (werkzeug 3.1.8)

Found by: trivy:dev-ceiling

werkzeug: werkzeug: Denial of Service via safe_join() Windows special device paths

LOW -- CVE-2026-111749 (aiohttp 3.14.3)

Found by: trivy:runtime-floor, trivy:runtime-floor-pydantic-v2

aiohttp: aiohttp: Host-Only cookie protection bypass via untrusted subdomain

LOW -- CVE-2026-112907 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: On Windows an oplock on a soft lock's marker holds SoftFileLock.acquire() past its timeout and blocks the stale break

LOW -- CVE-2026-112912 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Information disclosure via symbolic link following in SoftFileLock

LOW -- CVE-2026-112913 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: ReadWriteLock on Windows acts on SQLite side files another local user places beside its database

LOW -- CVE-2026-112941 (filelock 4.1.0)

Found by: trivy:dev-ceiling

filelock: filelock: Unauthorized file write via lock directory replacement

UNKNOWN -- CVE-2026-111063 (GHSA-494j-54xm-rwp3) (aiohttp 3.14.3)

Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2

### Summary The Secure attribute was not being enforced for the shared cookie. ### Impact It may be possible to send a shared cookie marked Secure through an unencrypted request.

UNKNOWN -- CVE-2026-111064 (GHSA-5wr8-gcqf-gqf3) (aiohttp 3.14.3)

Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2

### Summary The keepalive timeout was not used during the initial portion of a request. ### Impact An attacker could keep an idle connection open indefinitely before sending any data. ### Workaround Use a reverse proxy (as recommended for all production deployments) with sensible keepalive limits.

UNKNOWN -- CVE-2026-111065 (GHSA-6cjc-53gc-5rqm) (aiohttp 3.14.3)

Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2

### Summary An overflow in Max-Age processing can skip closing a connection. ### Impact An attacker may be able to exhaust the connection pool temporarily, until garbage collection resolves the connections.

UNKNOWN -- CVE-2026-111066 (GHSA-9xw5-w5jj-pvcg) (aiohttp 3.14.3)

Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2

### Summary An attacker can exhaust file descriptors with specially crafted multipart requests. ### Impact If a handler uses `Request.post()`, it may be possible for an attacker to use an unlimited number of file descriptors, potentially resulting in resource exhaustion.

UNKNOWN -- CVE-2026-111748 (GHSA-f9xw-jh8m-3mwq) (aiohttp 3.14.3)

Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2

### Summary An attacker sending an absolute-form request can spoof the scheme used. ### Impact If user code depends on the `Request.scheme` attribute for anything security related, an attacker may be able to circumvent this logic, tricking the application into thinking a connection is encrypted when it is not, or vice versa. ### Workaround A WAF rule to reject absolute-form requests (legitimate requests should only use this form for proxies).

UNKNOWN -- CVE-2026-111749 (GHSA-gx76-c99x-2c96) (aiohttp 3.14.3)

Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2

### Summary A subdomain can remove the Host-Only flag from an existing cookie to a parent domain. ### Impact A user accessing untrusted subdomains could see their Host-Only protections stripped from cookies. Given most usecases won't reflect these cookies to a browser, the impact is limited.

UNKNOWN -- CVE-2026-111750 (GHSA-pqxq-w44r-73xw) (aiohttp 3.14.3)

Found by: pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2

### Summary The pure Python parser is vulnerable to an HTTP request smuggling attack. ### Impact If users are using the Python parser (`AIOHTTP_NO_EXTENSIONS`, or not a standard wheel installed), then an application may be vulnerable to a request smuggling attack. ### Workaround Switch to the default C parser.

UNKNOWN -- CVE-2026-114605 (GHSA-45c3-73f7-pv4m) (dnspython 2.8.0)

Found by: pip-audit:dev-ceiling, pip-audit:runtime-ceiling, pip-audit:runtime-floor, pip-audit:runtime-floor-pydantic-v2

### Impact A maliciously crafted DNS message may cause dns.name.from_wire_parser() to use excessive CPU for DNS name decompression. Applications that process untrusted DNS wire form messages with dnspython may be degraded or DoS'd by the extra CPU use required. ### Patches This problem is fixed in dnspython 2.9.0. ### Workarounds There are no known workarounds. ### Credit Evgenios Gkritsis, Department of Informatics, University of Piraeus & Athena Research Center, Greece Constantinos Patsakis, Department of Informatics, University of Piraeus & Athena Research Center, Greece George Stergiopoulos, Department of Informatics, Athens University of Economics and Business, Greece

UNKNOWN -- CVE-2026-112906 (GHSA-2g95-wg33-c5x2) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`SoftFileLock` and `MarkerSoftFileLock` evict an unparsable marker (the lock file at `<path>`, whose presence says a process holds the lock) once a waiting contender has watched it unchanged for two seconds. `SoftFileLease` expires a lease the same way. The watch tells two looks apart by the marker's modification time (mtime) and inode number (the kernel's identity for a file, independent of its name) alone. Another local user (the other user below) who can create files in the lock's directory, a sticky `/tmp` included (the sticky bit is a directory flag that lets only a file's owner remove it), parks an empty file of its own at the lock path. It dates that file to a future tick of the kernel's coarse clock (a clock that advances in steps of 4 ms), lets the waiters of the user running the lock (the lock user below) watch it past two seconds, and unlinks it in that tick. On a filesystem that hands a freed inode number straight back (ext4, overlayfs on ext4) the lock user's next marker repeats both values. It inherits the time spent watching the other user's file, and a second waiter removes it while its owner holds the lock. Two of the lock user's processes then run the critical se…

UNKNOWN -- CVE-2026-112907 (GHSA-567q-5qvw-pf92) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

On Windows the soft locks (`SoftFileLock`, `MarkerSoftFileLock`, `SoftFileLease`, their async forms, and a `FileLock` that fell back to a soft lock) read their marker by path. The marker is the lock file whose presence says a process holds the lock. Each `acquire()` attempt that finds a marker opens it with `os.open` to read the holder's process id, and the lock renames and deletes a marker it judges stale, by path. On Windows each of these calls waits for an oplock. An oplock (opportunistic lock) is a request by a process that holds a handle on a file to be told before another process opens, renames or deletes that file; the other process waits until the holder answers the break or closes its handle. Another local account that can open the marker for reading can take a Level 1 oplock on it while no process holds it open, and leave the break unanswered. Every `acquire()` by the user running the lock (below: the lock user) then waits inside the open, past its `timeout`, `blocking=False` and `cancel_check`, and a stale marker under that oplock is not broken. Mutual exclusion holds and the lock touches no other file. Affected versions are filelock 3.22.0 through 4.2.0 on Windows. The…

UNKNOWN -- CVE-2026-112908 (GHSA-6627-m3xw-93mp) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`StrictSoftFileLock` and `AsyncStrictSoftFileLock` apply the caller's `mode` to the sentinel (the lock file at `<path>`) and to both claim files (the files whose presence says a process wants or holds the lock). They create the two directories that hold the claims, `<path>.filelock` and `<path>.filelock/claims`, with a bare `mkdir()`. That gives `0o777` filtered through the umask (a per-process mask that removes permission bits from new files and directories) or, under a parent with a default ACL (an access control list on a directory that sets the permissions of entries created inside it), through that ACL. A hold consists of two claim names in that directory, which has no sticky bit (a directory flag that lets only a file's owner remove it). When the environment leaves another local user (the other user below) a write bit on the directory, that user can unlink the holder's `0600` claims. Three settings do this: umask `000` in a sticky directory such as `/tmp`, umask `002` with the other user in the directory's group, or a default ACL on the lock's parent that grants the group write (the kernel then ignores the umask). After the unlink, the next contender of the holder's account …

UNKNOWN -- CVE-2026-112909 (GHSA-69hj-f68j-2879) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`UnixFileLock`, the backend of `FileLock` and `AsyncFileLock` on Unix, empties whatever regular file it finds at the lock path once it holds the `flock` (a kernel lock on an open file). With an explicit `mode` it also chmods that file (sets its permission bits), whether or not this acquire created it. Another local user who can rename or hard-link one of the files of the user running the lock (below: the lock user) onto the lock path gets that file truncated by the lock user's next `acquire()`. A hard link is a second name for the same file. With a mode such as `0o666` the file, still owned by the lock user, also becomes readable and writable by that other user. The other user can then read and alter everything the lock user writes to it afterwards. `O_NOFOLLOW`, the defence added for the symlink variant (CVE-2025-68146), does not see a renamed file or a hard link. The rename route needs the file's directory to be writable without the sticky bit (a directory flag that lets only a file's owner remove or rename it). The hard-link route into a sticky directory such as `/tmp` needs `fs.protected_hardlinks=0`, a Linux kernel setting. Affected versions are every filelock release up to a…

UNKNOWN -- CVE-2026-112910 (GHSA-8mx5-7m5m-r77g) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

filelock on Windows ignores the `mode` argument. `FileLock(path, mode=0o600)` creates the same file as `FileLock(path)`: one with no security descriptor of its own (the Windows record that says who may access a file). Its access list, or ACL, is whatever the lock directory hands down to new files. filelock creates the `ReadWriteLock` database, which it asks to be `0o600`, the same way. In a directory whose inheritable ACL grants other local accounts access to new files, those accounts can open the lock file or database. They can take the byte-range lock (a lock on a span of bytes in a file) once the owner releases it and keep the owner's later `acquire()` calls waiting or timing out. They can read holder metadata an `on_acquired` hook left in a `preserve_lock_file=True` file. Where the directory hands down modify access, they can write to both files. `lock.mode` still reports `0o600`. The documentation neither promises an ACL on Windows nor says that Windows drops the mode. On Unix the same mode keeps other accounts out. Mutual exclusion between processes that follow the protocol holds on either platform. Affected versions are filelock 3.10.0 through 4.2.0 on Windows. Anthropic's …

UNKNOWN -- CVE-2026-112911 (GHSA-9c4x-gm8v-wgc4) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`StrictSoftFileLock`, `AsyncStrictSoftFileLock`, `SoftReadWriteLock` and `AsyncSoftReadWriteLock` keep their whole ownership state as files in a directory derived from the lock path (`<path>.filelock/claims`, `<path>.rw/{gen,holders}`). When that directory already exists they adopt it after checking only that it is a real directory, not who owns it. Another local user who can create names in the lock's directory can create the tree before the first acquire on that path by the user running the lock (below: the lock user). In `/tmp`, `/var/tmp` or another sticky shared directory any user can do that; the sticky bit is a directory flag that lets only a file's owner remove or rename it. The other user then owns the tree. They can unlink the lock user's claims while the lock user holds the lock, so a second process of the lock user, root included, enters the same critical section and neither process sees an error. Against `SoftReadWriteLock` the same position also admits two writers with `on_compromise` silent. It redirects the lock user's own creates and renames into a directory the other user picks (the scanner replaced a repository's `.git/HEAD` with a filelock record written with t…

UNKNOWN -- CVE-2026-112912 (GHSA-9j6q-wvj5-jgjg) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`raise_on_not_writable_file()` is the check that `SoftFileLock` and the locks sharing its acquire path run before every attempt. It looks at the lock path with `os.lstat`, so that it judges a planted symlink (a file that points at another path) by itself. When the node has no owner-write bit, it then calls `os.access(filename, os.W_OK)`, which follows symlinks. A local user who can create entries in the lock's directory can swap the path between a mode-`0466` file and a symlink to a path of their choosing. The second call then reports on the symlink's target with the permissions of the user running the lock (below: the lock user). The lock user's `acquire()` ends in `PermissionError` within a fraction of a second when the target is missing or not writable by the lock user, and in the ordinary `Timeout` otherwise. That yields one bit per watched acquire. The bit says whether a path exists and is writable by the lock taker. It covers paths under directories the other user cannot search, or any path when root takes the lock. The lock does not open, create or modify anything through the symlink. On Linux, `fs.protected_symlinks` (a kernel setting that refuses to follow another user's …

UNKNOWN -- CVE-2026-112913 (GHSA-9vhv-jxww-xfm5) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

On Windows, `ReadWriteLock` and `AsyncReadWriteLock` (the SQLite-backed reader/writer lock) connect SQLite to the lock database by its path, in every directory. SQLite derives three side files from that path: `<database>-journal`, the rollback journal (pages saved to undo an interrupted write); `<database>-wal`, the write-ahead log (changes kept outside the main file); and `<database>-shm`, the shared-memory index of the WAL. SQLite acts on whichever of these it finds beside the database before the lock runs any statement. Another local account that can create files in the database's directory, but not delete files of other accounts there, places such a side file beside the database and denies everyone `DELETE` on it, which a file's creator may do. `C:\Windows\Temp` (the temporary directory of services, granting `BUILTIN\Users` create but not delete) and `C:\Users\Public` are such directories. With a `-wal` in place, every `read_lock()` and `write_lock()` of the user running the lock (below: the lock user) raises `sqlite3.OperationalError: disk I/O error` at once, whatever `timeout` says, until that account removes its file; the lock user cannot. With a `-journal` beside a lock da…

UNKNOWN -- CVE-2026-112914 (GHSA-crv4-6mhj-j5jh) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

When a soft-lock stale break finds that the marker (the lock file at `<path>`) it renamed aside was a live one recreated by a successor, the restore branch of `break_lock_file()` checks the break name with `lstat` (a check that reads a name without following a symbolic link) and then calls `os.link(break_path, lock_file)` by name. On CPython 3.12 and later on Linux (and on macOS) that call follows a symbolic link (a file that redirects to another path). A local user (the other user below) who can write a shared lock directory without the sticky bit (a directory flag that lets only a file's owner rename or remove it) replaces the break name with a symbolic link between those two calls. The `SoftFileLock`, `MarkerSoftFileLock`, `SoftFileLease` or `lifetime` break of the user running the lock (the lock user below) then creates a hard link (a second name for the same file), in that directory, to any of the lock user's own files on the same filesystem. That includes files inside directories the other user cannot enter and links that `fs.protected_hardlinks` (a Linux setting that forbids hard links to files one does not own) refuses the other user when it asks itself. The link exposes t…

UNKNOWN -- CVE-2026-112915 (GHSA-cwqr-hh33-gh44) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`ReadWriteLock` and `AsyncReadWriteLock` (the SQLite-backed reader/writer lock) run `PRAGMA journal_mode=MEMORY` on a fresh connection for every acquire. That statement makes SQLite load the whole schema (the `sqlite_master` table, which lists every table and index with its `CREATE` text) of whatever file sits at the lock path. The caller's `timeout` reaches SQLite only as `busy_timeout`, which bounds waits for another connection's lock, not schema loading. The only content checks reject non-regular files and WAL mode (write-ahead log, an SQLite mode that keeps changes in a side file). A local user who can place or overwrite the file at a `ReadWriteLock`'s database path can therefore make every `acquire_read` / `acquire_write` of every process using that lock ignore its `timeout` and `blocking=False`. That position needs a non-sticky shared directory, or a database owned by the user running the lock (below: the lock user) that other users may write. One 37 KB crafted file stalls each acquire for as long as its author chooses while the process allocates about 1 GB. A second 28 KB layout makes the acquire of a free lock run without end, spinning at 100% CPU and ignoring Ctrl-C. The …

UNKNOWN -- CVE-2026-112934 (GHSA-fj95-fr6c-h845) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`SoftReadWriteLock` (and `AsyncSoftReadWriteLock`, which wraps one) refreshes its holder record (the file under `<path>.rw/holders/` that says a process holds or wants the lock) on every poll of a waiting acquire and on every heartbeat (the periodic refresh a holder runs to keep its record fresh). It does so by reopening `<path>.rw/holders/<token>` by name with a plain blocking `O_WRONLY | O_NOFOLLOW` open and writing at offset 0, without checking what it opened. `O_NOFOLLOW` makes the open fail only when the final name is a symbolic link (a file that redirects to another path). A different local user (the other user below) who owns the lock's `.rw` tree reads the token of the user running the lock (the lock user below) from the `holders/` listing and renames another node over the record. The other user owns the tree because it created it first in a sticky directory such as `/tmp` (the sticky bit is a directory flag that lets only a file's owner rename or remove it), or because it can write a lock directory without the sticky bit. A FIFO (a named pipe: a file whose open for writing blocks until some process opens it for reading) makes the lock user's `write_lock()` / `read_lock()`…

UNKNOWN -- CVE-2026-112935 (GHSA-fq56-3cx3-fjxp) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

The stale-lock break shared by `SoftFileLock`, `MarkerSoftFileLock` and `SoftFileLease` (and their async variants, and a `FileLock` that has fallen back to a soft lock on `ENOSYS`, the "not implemented" error) recognises the marker it judged stale by two values. The marker is the lock file at `<path>`, whose presence says a process holds the lock. The values are its inode number (the kernel's identity for a file, independent of its name) and its modification time (mtime) not being newer. The check runs after the contender has already closed the marker, so nothing keeps the inode allocated. On a filesystem that hands a freed inode number straight to the next file (ext4, xfs, overlayfs on them) the next holder's marker can carry that number. A contender still between its read and its break then renames and unlinks the live marker. Another local user (the other user below) who can create files in the lock's directory, a sticky `/tmp` included (the sticky bit is a directory flag that lets only a file's owner remove it), forces this at will. It plants a marker with a stale owner record and a modification time in the future and unlinks it as soon as a contender has read it. Two processe…

UNKNOWN -- CVE-2026-112937 (GHSA-jqc4-5cvw-7w85) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`ReadWriteLock` and `AsyncReadWriteLock` (the SQLite-backed reader/writer lock) remove their private `.filelock-*` link directories with `shutil.rmtree` (a recursive delete) on a remembered path. They do not check that the path still names the directory they created. This happens on the hard-link route (a hard link is a second name for the same file). That route is every connection on macOS since 4.1.1 and any POSIX process without a usable `/proc/self/fd` (a Linux path that names the process's own open files), such as a chroot or container that does not mount `/proc`. Another local user who can rename entries in the directory that holds the lock database can rename one of the directories of the user running the lock (below: the lock user) onto the link directory's name, or onto a forged dead-holder name. Such a lock directory is a `0777` or group-writable cache, build or project directory without the sticky bit (a directory flag that lets only a file's owner remove or rename it). The lock user's process then deletes that tree and everything in it with the lock user's permissions, and reports no error. Stock Linux with `/proc` mounted is not affected. Affected versions are fileloc…

UNKNOWN -- CVE-2026-112938 (GHSA-m462-7rxw-wvpg) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`StrictSoftFileLock` and `AsyncStrictSoftFileLock` check `<path>.filelock` (the coordination directory that holds the lock's state) with one `lstat` call on its name. `lstat` reports what a name is without following a symbolic link (a file that redirects to another path). After that check, the code reaches `<path>.filelock/claims` by pathname for every later operation (`mkdir`, scan, publish, link, unlink). `_open_directory` passes `O_NOFOLLOW` (a flag that makes an open fail when the final name is a symbolic link), but the flag covers only the final `claims` component. The kernel follows a symbolic link in any earlier component. Another local user (the other user below) who can rename `<path>.filelock` exchanges it for a symbolic link after the check. In a shared directory without the sticky bit (a directory flag that lets only a file's owner rename or remove it), any user with write access can do this. Where the shared directory is sticky, such as `/tmp`, only the user who created `<path>.filelock` before the user running the lock (the lock user below) first used it can. The lock user's process (root's, if root takes the lock) then creates a `claims` directory and claim files (t…

UNKNOWN -- CVE-2026-112939 (GHSA-rfpc-qcw5-3pc4) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`SoftFileLock`, `MarkerSoftFileLock`, `SoftFileLease`, their async variants and a `FileLock` that has fallen back to a soft lock on `ENOSYS` decide from the record inside the marker file whether its owner is gone. The marker is the file whose presence says a process holds the lock. They do not check who could have written that record. A local user who can write the marker but cannot remove it rewrites the holder's record to name a dead PID (process id). That position arises with an explicit `mode` with group or other write bits, or the default mode under a lax umask (the process setting that strips permission bits from new files), in a sticky or otherwise non-removable directory. The sticky bit is a directory flag that lets only a file's owner remove or rename it. The next contender running as the holder's account, or root, judges the lock stale, removes the live marker on that user's behalf and acquires it. Two processes then run the critical section together and neither gets an error. Affected versions are filelock 3.22.0 through 4.2.0 (finding `ANT-2026-W1H9NXUH`). ## Severity **CVSS 3.1 `CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N` scores 4.7 (Medium).** `AV:L` (local): the o…

UNKNOWN -- CVE-2026-112940 (GHSA-v4x8-3wr5-3wq8) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`ReadWriteLock` and `AsyncReadWriteLock` (the SQLite-backed reader/writer lock) hand SQLite a name they do not control. On Linux the lock validates its database through a descriptor (the number the kernel gives a process for an open file). It then connects SQLite to `/proc/self/fd/<n>`, a Linux path that names the process's own open file `n`. SQLite turns that path back into a plain path and reopens it by name, following symlinks (a symlink is a file that points at another path). On every POSIX route SQLite also acts on `-journal`, `-wal` and `-shm` files it finds beside that name. Those are SQLite's side files: the rollback journal (pages saved to undo an interrupted write), the write-ahead log or WAL (changes kept outside the main file), and the shared-memory index for the WAL. Another local user who can create or rename entries in the directory that holds the lock database can turn this against the user running the lock (below: the lock user). Such a directory is a `0777` or group-writable cache, build or project directory without the sticky bit (a directory flag that lets only a file's owner remove or rename it). That other user can make the lock user's ordinary `read_lock()` …

UNKNOWN -- CVE-2026-112941 (GHSA-wfhq-q4j2-c37m) (filelock 4.1.0)

Found by: pip-audit:dev-ceiling

`SoftReadWriteLock` (and `AsyncSoftReadWriteLock`, which wraps one) checks once per lock object, by name, that `<path>.rw`, `<path>.rw/gen` and `<path>.rw/holders` are real directories and not symbolic links (files that redirect to another path). It then keeps only a boolean. Every later record operation resolves the full path again, and `O_NOFOLLOW` (a flag that makes an open fail when the final name is a symbolic link) protects the last component only. Another local user (the other user below) who can write the directory holding the lock, or who created `<path>.rw` first in a sticky directory such as `/tmp` (the sticky bit is a directory flag that lets only a file's owner rename or remove it), can put a tree under that name whose `gen` or `holders` is a symbolic link into a directory of the user running the lock (the lock user below). A long-running process of the lock user that has already passed the check then creates, renames over and deletes files there with the lock user's privileges, including in `0700` directories the other user cannot open. The names and bytes are filelock's own lock records, not chosen by the other user. The scanner's reproducer replaces `.git/HEAD` in …

UNKNOWN -- PYSEC-2026-4305 (CVE-2026-104843, GHSA-2cv4-cqwr-gwf7) (uv 0.12.17)

Found by: pip-audit:dev-ceiling

### Impact In versions of uv from 0.12.7 to 0.12.18 on Windows, uv could be induced into writing a file outside of the installation prefix during wheel installation. A malicious wheel could use this to place an executable outside of the intended environment, including in a directory already present on the user's PATH. This vulnerability only affects Windows hosts; no other platforms are affected. ### Patches uv 0.12.18 and newer address this vulnerability. Users are encouraged to upgrade to 0.12.18. ### Workarounds There is no workaround other than upgrading to uv 0.12.18.

UNKNOWN -- PYSEC-2026-4321 (GHSA-hq85-5cpj-mr62) (uv 0.12.17)

Found by: pip-audit:dev-ceiling

By default, uv verifies TLS connections against a vendored copy of the `webpki-root-certs` bundle. Versions before 0.13.4 include the `emSign ECC Root CA - G3` root. Eight eMudhra intermediate CA certificates that chain to that root have compromised private keys, and the CA has revoked them. An attacker with one of the compromised keys can issue certificates that uv accepts for any hostname, and can be used to issue certificates to enable MITM attacks. uv 0.13.4 removes the root from its vendored bundle, following `webpki-root-certs` 1.0.10. Upgrade to 0.13.4 or later.

UNKNOWN -- PYSEC-2026-4312 (CVE-2026-102598, GHSA-g6x2-hccm-hh4m) (werkzeug 3.1.8)

Found by: pip-audit:dev-ceiling

Werkzeug's `safe_join` function allows Windows device names as filenames when they have an empty ADS marker on NTFS. This was previously reported as https://github.com/pallets/werkzeug/security/advisories/GHSA-hgf8-39gv-g3f2, but the added filtering failed to account for the fact Windows allows special device names with an empty ADS marker, such as `NUL:`. `send_from_directory` uses `safe_join` to safely serve files at user-specified paths under a directory. If the application is running on Windows and NTFS, and the requested path ends with a special device name, the file will be opened successfully, but reading will hang indefinitely.

How to fix

Raise the affected lower bound in pyproject.toml ([project].dependencies, or the pin in the dev dependency group) to at least the Fixed in version above, then run uv lock. Because this package publishes open >= ranges, the floor is what consumers can actually install -- bumping only the resolved version does not close the hole.

This audit resolves without the 7-day publish-age cooldown (exclude-newer) in [tool.uv], but uv lock applies it. If uv lock says the fixed version was filtered by exclude-newer, add exclude-newer-package = { <package> = false } under [tool.uv] in pyproject.toml, run uv lock and commit both files. Once the release is 7 days old, remove the entry and run uv lock again.

An advisory with no fix available does not block the build -- it is reported here so it can be tracked, but no version bump can resolve it. Suppression files are deliberately not honoured: the scan runs with --ignorefile /dev/null so nothing can disappear from this report silently.

Bumps [multidict](https://github.com/aio-libs/multidict) from 6.8.0 to 6.9.1.
- [Release notes](https://github.com/aio-libs/multidict/releases)
- [Changelog](https://github.com/aio-libs/multidict/blob/master/CHANGES.rst)
- [Commits](aio-libs/multidict@v6.8.0...v6.9.1)

---
updated-dependencies:
- dependency-name: multidict
  dependency-version: 6.9.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot
dependabot Bot force-pushed the dependabot/uv/multidict-6.9.1 branch from e875715 to 2c99386 Compare October 30, 2026 18:49

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

⌂ Proxy