diff --git a/docs/development.md b/docs/development.md index 566c9872..10a53bf6 100644 --- a/docs/development.md +++ b/docs/development.md @@ -100,6 +100,15 @@ version is pinned so relocking always produces the same output: When bumping the pin, change both `UV_VERSION` in the `justfile` and the `required-version` floor in `pyproject.toml` together. +### Fixing a CVE in a transitive dependency + +When the `Dependency Audit` job flags a package VIP does not declare directly, +raise a floor in `[tool.uv] constraint-dependencies` (for example +`"urllib3>=2.8.0"`) and run `just relock`. The `Lockfile Guard` job rejects a +`uv.lock` change that is not paired with a `pyproject.toml` change, and the +constraint is that paired change. It also stops a later relock from resolving +back to a vulnerable version. + ### Resolving a uv.lock merge conflict Never hand-edit conflict markers in `uv.lock`. Take either side wholesale, then diff --git a/pyproject.toml b/pyproject.toml index a507e89b..6baf6858 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -151,6 +151,9 @@ build-backend = "hatchling.build" # floor rejects those versions for every uv command; `just relock` pins an exact # version on top of it. See docs/development.md ("The lockfile"). required-version = ">=0.11" +# urllib3 is transitive. Floor it at the first release that fixes +# CVE-2026-97687/97688/97689 so a relock cannot resolve back to a vulnerable 2.7.x. +constraint-dependencies = ["urllib3>=2.8.0"] [tool.hatch.build.targets.wheel] packages = ["src/vip", "src/vip_tests"] diff --git a/uv.lock b/uv.lock index d182b9a5..f86338ae 100644 --- a/uv.lock +++ b/uv.lock @@ -9,6 +9,9 @@ resolution-markers = [ "python_full_version < '3.11'", ] +[manifest] +constraints = [{ name = "urllib3", specifier = ">=2.8.0" }] + [[package]] name = "anyio" version = "4.15.1" @@ -2628,11 +2631,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.7.0" +version = "2.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", size = 458972, upload-time = "2026-09-15T19:29:36.253Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, + { url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", size = 135717, upload-time = "2026-09-15T19:29:34.577Z" }, ] [[package]]