Vulners Python SDK 4.5.0
A maintenance release — the SDK's own API is unchanged. It moves the dependency set off every
release that carried an open advisory, and then on to the newest release of everything.
Security
Four advisories were critical, and all four sit on paths this client actually uses:
| Package | Was | Now | Why it matters here |
|---|---|---|---|
| brotli | 1.2.0 | 1.2.1 | out-of-bounds write in the decoder, which runs on every response a server answers with Content-Encoding: br
|
| certifi | 2026.7.22 | 2026.10.23 | the older bundle ships emSign root CAs whose intermediate keys were compromised |
| anyio | 4.13.0 | 4.15.1 | TLSStream encoded host names with IDNA 2003, which enables certificate spoofing
|
| authlib | 1.7.2 | 1.9.1 | empty JWS signatures and empty HMAC keys were accepted — signature forgery (reaches this project only through the mcp extra)
|
Also mcp to 1.30.0, opentelemetry-api to 1.45.1, and dnspython to 2.9.0 on Python 3.11+ —
upstream's fix for that one requires 3.11, so the 3.10 leg of the lockfile stays on 2.8.0.
What this means if you just install the package: the entries above are lockfile contents, and
the lockfile governs this repository's CI, not your environment — pip install vulners resolves
these transitively from PyPI and already picked the patched releases up. The exception is
brotli, a declared runtime dependency whose floor still admitted the vulnerable 1.2.0; from
this release it is brotli>=1.2.1. That is the only change to published metadata besides the
mcp extra below.
Changed
- The
mcpextra now accepts fastmcp 4 (fastmcp>=2.0,<5), over the officialmcp2.3.0
SDK. Worth knowing before upgrading: fastmcp 4 rides onhttpx2— the httpx 2.x line, published
under that name by Pydantic — sopip install "vulners[mcp]"ends up with two HTTP stacks,
fastmcp'shttpx2alongside thehttpx0.28 this SDK uses itself.vulners-mcp, its seven
tools and its configuration are unchanged, and the server is exercised against the live API on
the new stack.
Fixed
- The 100% branch-coverage gate no longer fails at random. The "a sibling range failed, skip
queued work" branch of the parallel archive download was only reached when the event loop
happened to interleave the transport's I/O a particular way, so it missed in roughly half of
runs — including on the previous dependency set. It is now pinned by a test where the skip is
the scheduler's only possible outcome.
Internal
- 63 locked dependencies upgraded, 6 added, 14 removed. Majors among them: mypy 2.4.1,
pytest 9.2.0, ruff 0.17.3, msgspec 0.22, rich 15, python-dateutil 3 — none needed a source
change. The lockfile's resolution cutoff moved with them and now keeps a one-day quarantine
instead of sitting months back. - Supply-chain review of the refreshed tree: every artifact resolves from pypi.org and is pinned
by sha256, OSV reports no advisory against the locked set other than the dnspython note above,
and each newly added package was checked by hand. Three of them read like typosquats and are
not —httpx2andhttpcore2are the httpx 2.x line maintained by Pydantic, and
httpx2-jsfetchis its Pyodide transport, which the lockfile marks
sys_platform == 'emscripten'and therefore never installs off the browser. - Pinned GitHub Actions and the uv toolchain are current:
actions/checkoutv7.0.1 (which clears
the last Node 20 deprecation warning),astral-sh/setup-uvv10.3.3, uv 0.13.6 in CI, and the
uv_buildband moved to>=0.13.1,<0.14. CONTRIBUTING.mdnow documents the two environment rules this refresh made load-bearing: the
codegengroup cannot share a resolution with thetestgroup or themcpextra, and the
lockfile's resolution cutoff is deliberate rather than stale.
Full changelog: https://github.com/vulnersCom/api/blob/master/CHANGELOG.md