diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 90a9b6dc3..53093f827 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -52,7 +52,7 @@ repos: args: ["--baseline", ".secrets.baseline"] additional_dependencies: ["gibberish-detector"] - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.7 + rev: 0.11.6 # GHSA-pjjw-68hj-v9mw; matches [tool.uv] required-version hooks: - id: uv-lock - repo: local diff --git a/SECURITY.md b/SECURITY.md index b4203261b..b6a044cc5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -31,6 +31,8 @@ d. **[trivy](https://trivy.dev/latest/)**: Pre commit to GitHub scans Python dep e. **[ox.security](https://www.ox.security/)**: Monitors dependencies for vulnerabilities pre and post release on GitHub. +How we handle vulnerabilities in our Python dependency supply chain — including the default path of raising lower bounds in `pyproject.toml`, and the list of advisories we have consciously accepted because no upstream fix is available yet — is documented in [SUPPLY_CHAIN_VULNERABILITIES.md](SUPPLY_CHAIN_VULNERABILITIES.md). + ### 2. License Compliance Checks and Software Bill of Materials (SBOM) a. **[pip-licenses](https://pypi.org/project/pip-licenses/)**: Inspects and matches the licenses of all dependencies with allow list to ensure compliance with licensing requirements and avoid using components with problematic licenses. `licenses.csv`, `licenses.json` and `licenses_grouped.json` published [per release](https://github.com/aignostics/python-sdk/releases). diff --git a/SUPPLY_CHAIN_VULNERABILITIES.md b/SUPPLY_CHAIN_VULNERABILITIES.md new file mode 100644 index 000000000..cafb0a6f7 --- /dev/null +++ b/SUPPLY_CHAIN_VULNERABILITIES.md @@ -0,0 +1,132 @@ +# Supply-Chain Vulnerabilities + +This document describes how aignostics handles vulnerabilities in its Python +dependency supply chain. + +Aignostics is consumed both as an application (`uvx aignostics`, or the +Launchpad) and as a library that users add to their own project with +`uv add aignostics`, `pip install aignostics`, or any other resolver. In +both cases the user's tooling picks dependency versions against the +dependency metadata we publish with the aignostics package — our own +lockfile and any development-only constraints we apply locally are +invisible to consumers. The only way to keep a consumer from resolving a +known-vulnerable version of a dependency is therefore to set an +appropriate lower bound on the dependency metadata we publish, including +on transitive dependencies. + +This document covers: + +- **How we protect consumers** — our default response when a scanner + reports an advisory, and the fallback path when no upstream fix is + available yet. +- **Active acceptances** — the (short) list of advisories we have + consciously accepted because no upstream fix exists or the + vulnerability is not exploitable in how aignostics uses the package. + This is where **the actual residual risk lives**: each row records + severity, scope, downstream-exposure assessment, rationale, and the + condition under which the acceptance expires. +- **Enforced lower bounds for CVE protection** — the complete catalog of + lower bounds we currently set specifically to shield consumers from + advisories that already have an upstream fix. + +See [SECURITY.md](SECURITY.md) for the scanners that feed this process +(`pip-audit`, Dependabot, Renovate, trivy, ox.security). + +## How we protect consumers + +This is sharper than the default practice in the Python ecosystem, where +many libraries constrain only their direct dependencies or rely on their +own lockfile for protection. We deliberately maintain explicit lower +bounds on direct *and* transitive dependencies, annotated with the +relevant CVE / GHSA id, so both `uvx aignostics` and `uv add aignostics` +give consumers a dependency tree free of the advisories we are aware of. + +Our policy per finding: + +- **Upstream fix available** — raise the lower bound of the affected + package with an inline CVE / GHSA comment and refresh our lockfile. + The bound goes on the existing line for direct dependencies, and in + the transitive-overrides block of the same section for transitive + ones. If the package is only reachable through an optional extra the + bound goes in that extra; if the package is genuinely dev-only it goes + in the dev-group constraints. +- **No upstream fix yet, or not exploitable in our use** — add the + advisory to the "Active acceptances" table below (with severity, + downstream-exposure assessment, rationale, and a removal condition) + and suppress it in `pip-audit` so it does not block CI. We never + silently ignore a finding. + +## Active acceptances + +This is where the actual residual risk lives. Each row is an advisory for +which no upstream fix has been released yet — or for which the +vulnerability is not exploitable in how aignostics uses the package — +together with severity, exposure assessment, rationale, and the condition +under which the acceptance expires. + +- **Applies to** says when the vulnerable package reaches a consumer's + tree: *always* (every install), *with the `` extra* (only consumers + who install that extra), or *dev only* (never reaches consumers; + affects our tooling only). +- **Downstream exposure** says whether accepting the advisory leaves + consumers at risk: *None* (e.g. the package is dev-only for us), + *Partial* (only if a specific extra is installed), or *Full* (every + consumer install inherits the vulnerable version). + +| Advisory | Package (affected) | Severity | Applies to | Downstream exposure | Published | Accepted | Revisit by | Fix status | Rationale | Removal condition | Accepted via | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| [GHSA-58qw-9mgm-455v](https://github.com/advisories/GHSA-58qw-9mgm-455v) / [CVE-2026-3219](https://nvd.nist.gov/vuln/detail/CVE-2026-3219) — pip archive type confusion (tar+ZIP concatenation) | `pip` ≤ 26.0.1 | CVSS 4.6 Moderate (CWE-434) | dev only | **None** — `pip` is not shipped as a dependency of `aignostics`; consumers use their own pip. | 2026-04-20 | 2026-04-24 | 2026-05-24 | Fix merged in [pypa/pip#13870](https://github.com/pypa/pip/pull/13870) for milestone `26.1`; not yet released | Exploitation requires `pip install` on an attacker-crafted dual-format archive; aignostics installs only from PyPI and signed GitHub release artifacts. | pip `26.1` (or later) is released on PyPI. Raise the dev-only `pip>=25.3` lower bound to `pip>=26.1` with a `# CVE-2026-3219` comment and remove the ignore. | [PYSDK-93](https://aignx.atlassian.net/browse/PYSDK-93) | + +"Revisit by" is a soft deadline: when it passes, we re-check whether the +upstream fix landed or whether a newer advisory superseded this one. For +dev-only entries we revisit quarterly; for runtime entries with a known +upcoming fix, monthly. + +## Enforced lower bounds for CVE protection + +Every lower bound below is set with an inline CVE / GHSA comment so it is +visible to anyone reading the project metadata. These are the constraints +that prevent downstream consumers from resolving a known-vulnerable +version. + +- **Applies to** tells you when the constraint reaches a consumer's + dependency tree: *always* (affects every `uvx aignostics` and + `uv add aignostics`), *with the `` extra* (affects only consumers + who install that extra), or *dev only* (never reaches a consumer; + applies to our own tooling). +- **Severity** is the highest CVSS rating among the advisories protected + against, as reported by NVD. +- **Since** is the calendar date on which the lower bound was introduced + into `main`. + +| Package | Constraint | Protects against | Severity | Applies to | Since | +| --- | --- | --- | --- | --- | --- | +| `nicegui[native]` | `>=3.9.0,<4` | [CVE-2026-21871](https://nvd.nist.gov/vuln/detail/CVE-2026-21871), [CVE-2026-21873](https://nvd.nist.gov/vuln/detail/CVE-2026-21873), [CVE-2026-21874](https://nvd.nist.gov/vuln/detail/CVE-2026-21874) (≥3.5.0); [CVE-2026-25516](https://nvd.nist.gov/vuln/detail/CVE-2026-25516) (≥3.7.0); [CVE-2026-27156](https://nvd.nist.gov/vuln/detail/CVE-2026-27156) (≥3.8.0); [CVE-2026-33332](https://nvd.nist.gov/vuln/detail/CVE-2026-33332) (≥3.9.0) | Medium | always | 2026-01-09 (≥3.5.0); 2026-04-24 raised to ≥3.9.0 | +| `pyjwt[crypto]` | `>=2.12.0,<3` | [CVE-2026-32597](https://nvd.nist.gov/vuln/detail/CVE-2026-32597) | High | always | 2026-04-24 | +| `requests` | `>=2.33.0,<3` | [CVE-2026-25645](https://nvd.nist.gov/vuln/detail/CVE-2026-25645) | Medium | always | 2026-03-26 | +| `urllib3` | `>=2.6.3,<3` | [CVE-2026-21441](https://nvd.nist.gov/vuln/detail/CVE-2026-21441) | Medium | always | 2026-01-08 | +| `h11` | `>=0.16.0` | [CVE-2025-43859](https://nvd.nist.gov/vuln/detail/CVE-2025-43859) | Critical | always | 2025-12-10 | +| `tornado` | `>=6.5.5` | [CVE-2025-47287](https://nvd.nist.gov/vuln/detail/CVE-2025-47287) (≥6.5.0); [GHSA-78cv-mqj4-43f7](https://github.com/advisories/GHSA-78cv-mqj4-43f7) (≥6.5.5) | High | always | 2025-12-10 (≥6.5.0); 2026-04-24 raised to ≥6.5.5 | +| `urllib3` | `>=2.5.0` | [CVE-2025-50181](https://nvd.nist.gov/vuln/detail/CVE-2025-50181), [CVE-2025-50182](https://nvd.nist.gov/vuln/detail/CVE-2025-50182) | Medium | always | 2025-12-10 | +| `pillow` | `>=12.2.0` | [CVE-2025-48379](https://nvd.nist.gov/vuln/detail/CVE-2025-48379) (≥11.3.0); [CVE-2026-25990](https://nvd.nist.gov/vuln/detail/CVE-2026-25990) (≥12.1.1); [CVE-2026-40192](https://nvd.nist.gov/vuln/detail/CVE-2026-40192) (≥12.2.0) | High | always | 2025-12-10 (≥11.3.0); 2026-04-24 raised to ≥12.2.0 | +| `aiohttp` | `>=3.13.4` | [CVE-2025-53643](https://nvd.nist.gov/vuln/detail/CVE-2025-53643), CVE-2025-69223..69230 (≥3.13.3); [CVE-2026-22815](https://nvd.nist.gov/vuln/detail/CVE-2026-22815) (≥3.13.4) | High | always | 2026-01-06 (≥3.13.3); 2026-04-24 raised to ≥3.13.4 | +| `starlette` | `>=0.49.1` | [CVE-2025-54121](https://nvd.nist.gov/vuln/detail/CVE-2025-54121) (≥0.47.2); [GHSA-7f5h-v6xp-fcq8](https://github.com/advisories/GHSA-7f5h-v6xp-fcq8) (≥0.49.1) | Medium | always | 2025-12-10 | +| `lxml` | `>=6.1.0` | [CVE-2026-41066](https://nvd.nist.gov/vuln/detail/CVE-2026-41066) | High | always | 2025-12-10 (≥6.0.2); 2026-04-24 raised to ≥6.1.0 | +| `filelock` | `>=3.20.3` | [CVE-2025-68146](https://nvd.nist.gov/vuln/detail/CVE-2025-68146) (≥3.20.1); [CVE-2026-22701](https://nvd.nist.gov/vuln/detail/CVE-2026-22701) (≥3.20.3) | Medium | always | 2025-12-17 (≥3.20.1); 2026-04-24 raised to ≥3.20.3 | +| `marshmallow` | `>=3.26.2` | [CVE-2025-68480](https://nvd.nist.gov/vuln/detail/CVE-2025-68480) | Medium | always | 2025-12-23 | +| `pygments` | `>=2.20.0` | [CVE-2026-4539](https://nvd.nist.gov/vuln/detail/CVE-2026-4539) | Medium | always | 2026-04-24 | +| `cryptography` | `>=46.0.7` | [CVE-2026-39892](https://nvd.nist.gov/vuln/detail/CVE-2026-39892) | Medium | always | 2026-04-24 | +| `pydicom` | `>=3.0.2` | [CVE-2026-32711](https://nvd.nist.gov/vuln/detail/CVE-2026-32711) | High | always | 2026-04-24 | +| `pyasn1` | `>=0.6.3` | [CVE-2026-30922](https://nvd.nist.gov/vuln/detail/CVE-2026-30922) | High | always | 2026-04-24 | +| `lxml-html-clean` | `>=0.4.4` | [CVE-2026-28348](https://nvd.nist.gov/vuln/detail/CVE-2026-28348), [CVE-2026-28350](https://nvd.nist.gov/vuln/detail/CVE-2026-28350) | Medium | always | 2026-04-24 | +| `python-multipart` | `>=0.0.26` | [CVE-2026-24486](https://nvd.nist.gov/vuln/detail/CVE-2026-24486) (≥0.0.22); [CVE-2026-40347](https://nvd.nist.gov/vuln/detail/CVE-2026-40347) (≥0.0.26) | High | always | 2026-04-24 | +| `protobuf` | `>=6.33.5` | [CVE-2026-0994](https://nvd.nist.gov/vuln/detail/CVE-2026-0994) | High | always | 2026-04-24 | +| `nbconvert` | `>=7.17.1` | [CVE-2025-53000](https://nvd.nist.gov/vuln/detail/CVE-2025-53000) | High | with the `jupyter` extra | 2026-04-24 | +| `jupyter-core` | `>=5.8.1` | [CVE-2025-30167](https://nvd.nist.gov/vuln/detail/CVE-2025-30167) | High | with the `jupyter` extra | 2025-12-10 | +| `jupyterlab` | `>=4.4.9` | [CVE-2025-59842](https://nvd.nist.gov/vuln/detail/CVE-2025-59842) | Low | with the `jupyter` extra | 2025-12-10 | +| `marimo` | `>=0.23.0,<1` | [GHSA-2679-6mx9-h9xc](https://github.com/advisories/GHSA-2679-6mx9-h9xc) | Medium | with the `marimo` extra | 2026-04-24 | +| `pip` | `>=25.3` | [CVE-2025-8869](https://nvd.nist.gov/vuln/detail/CVE-2025-8869) | Medium | dev only | 2026-04-01 (>=5.3 — ineffective); 2026-04-24 raised to ≥25.3 | +| `uv` | `>=0.11.6` | [CVE-2025-54368](https://nvd.nist.gov/vuln/detail/CVE-2025-54368), [GHSA-w476-p2h3-79g9](https://github.com/advisories/GHSA-w476-p2h3-79g9), [GHSA-pqhf-p39g-3x64](https://github.com/advisories/GHSA-pqhf-p39g-3x64) (≥0.9.7); [GHSA-pjjw-68hj-v9mw](https://github.com/advisories/GHSA-pjjw-68hj-v9mw) (≥0.11.6) | Medium | dev only | 2025-12-10 (≥0.9.7); 2026-04-24 raised to ≥0.11.6 | +| `pytest` | `>=9.0.3,<10` | [CVE-2025-71176](https://nvd.nist.gov/vuln/detail/CVE-2025-71176) | Medium | dev only | 2026-04-24 | +| `virtualenv` | `>=20.36.1` | [pypa/virtualenv#3013](https://github.com/pypa/virtualenv/pull/3013) TOCTOU fix; bundles filelock ≥3.20.1 for [CVE-2025-68146](https://nvd.nist.gov/vuln/detail/CVE-2025-68146) | Medium | dev only | 2026-04-24 | +| `fonttools` | `>=4.60.2` | [CVE-2025-66034](https://nvd.nist.gov/vuln/detail/CVE-2025-66034) / [GHSA-768j-98cg-p3fv](https://github.com/advisories/GHSA-768j-98cg-p3fv) | Medium | dev only | 2025-12-10 | diff --git a/docs/partials/README_footer.md b/docs/partials/README_footer.md index 26a29209b..6c2523bf5 100644 --- a/docs/partials/README_footer.md +++ b/docs/partials/README_footer.md @@ -3,6 +3,9 @@ 1. Inspect our [security policy](https://aignostics.readthedocs.io/en/latest/security.html) with detailed documentation of checks, tools and principles. + How we handle vulnerabilities in our Python dependency supply chain is + documented in + [SUPPLY_CHAIN_VULNERABILITIES.md](https://github.com/aignostics/python-sdk/blob/main/SUPPLY_CHAIN_VULNERABILITIES.md). 1. Inspect how we achieve [operational excellence](https://aignostics.readthedocs.io/en/latest/operational_excellence.html) with information on our modern toolchain and software architecture. diff --git a/noxfile.py b/noxfile.py index 48f2040ed..72e9c53bf 100644 --- a/noxfile.py +++ b/noxfile.py @@ -145,23 +145,18 @@ def audit(session: nox.Session) -> None: """Run security audit and license checks.""" _setup_venv(session) - # pip-audit to check for vulnerabilities + # pip-audit to check for vulnerabilities. + # Every --ignore-vuln entry must correspond to a row in SUPPLY_CHAIN_VULNERABILITIES.md + # with rationale, scope, downstream-exposure assessment, and removal condition. try: session.run( - # TODO(Helmut): Ignore pip vuln until pip achieved to build v5.3 "pip-audit", "-f", "json", "-o", "reports/vulnerabilities.json", "--ignore-vuln", - "GHSA-4xh5-x5gv-qwph", # https://pyinstaller.org/en/stable/license.html - "--ignore-vuln", - "CVE-2025-53000", # no fix available - "--ignore-vuln", - "CVE-2025-69872", # no fix available - "--ignore-vuln", - "CVE-2026-4539", # no fix available + "CVE-2026-3219", # pip archive type confusion; fix in unreleased 26.1. See SUPPLY_CHAIN_VULNERABILITIES.md ) except CommandFailed: _format_json_with_jq(session, "reports/vulnerabilities.json") diff --git a/pyproject.toml b/pyproject.toml index b80718ab7..c1ed2d37f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,7 +78,7 @@ dependencies = [ # From Template "fastapi[all,standard]>=0.123.10", "humanize>=4.14.0,<5", - "nicegui[native]>=3.5.0,<4", # CVE-2026-21871, CVE-2026-21871, CVE-2026-21873, CVE-2026-21874 all require >=3.5.0 + "nicegui[native]>=3.9.0,<4", # CVE-2026-21871, CVE-2026-21873, CVE-2026-21874 (>=3.5.0); CVE-2026-25516 (>=3.7.0, #418); CVE-2026-27156 (>=3.8.0, #448); CVE-2026-33332 (>=3.9.0, #498). CVE-2026-39844 (>=3.10.0, #531) not yet merged. "packaging>=26,<27", "platformdirs>=4.5.1,<5", "psutil>=7.1.3,<8", @@ -111,7 +111,7 @@ dependencies = [ "procrastinate>=3.5.3", "fastparquet>=2025.12.0,<2026.0.0; python_version < '3.14'", "pyarrow>=22.0.0,<23; python_version >= '3.14'", - "pyjwt[crypto]>=2.10.1,<3", + "pyjwt[crypto]>=2.12.0,<3", # CVE-2026-32597 requires >=2.12.0 (Renovate #475) "python-dateutil>=2.9.0.post0,<3", # "pywebview[qt6]>=5.4,<6; sys_platform == 'linux'", "requests>=2.33.0,<3", # CVE-2026-25645 requires >= 2.33.0 @@ -125,19 +125,26 @@ dependencies = [ "urllib3>=2.6.3,<3", # CVE-2026-21441 requires >= 2.6.3 "wsidicom>=0.28.1,<1", "fastmcp>=3.2.0,<4", - # Transitive overrides + # Transitive overrides (see SUPPLY_CHAIN_VULNERABILITIES.md) # WARNING: one cannot negate or downgrade a dependency required here. use override-dependencies for that. "rfc3987; sys_platform == 'never'", # GPLv3 "h11>=0.16.0", # CVE-2025-43859 - "tornado>=6.5.0", # CVE-2025-47287 - "urllib3>=2.5.0", # CVE-2025-50181, CVE-2025-50182, - "pillow>=11.3.0", # CVE-2025-48379, - "aiohttp>=3.13.3", # CVE-2025-53643, CVE-2025-69223, CVE-2025-69224, CVE-2025-69228, CVE-2025-69229, CVE-2025-69230, CVE-2025-69226, CVE-2025-69227, CVE-2025-69225 + "tornado>=6.5.5", # CVE-2025-47287 (>=6.5.0); GHSA-78cv-mqj4-43f7 (>=6.5.5, Renovate #472) + "urllib3>=2.5.0", # CVE-2025-50181, CVE-2025-50182 + "pillow>=12.2.0", # CVE-2025-48379 (>=11.3.0); CVE-2026-25990 (>=12.1.1, Renovate #428); CVE-2026-40192 (>=12.2.0, Renovate #539) + "aiohttp>=3.13.4", # CVE-2025-53643, CVE-2025-69223..9 (>=3.13.3); CVE-2026-22815 (>=3.13.4, Renovate #527) "starlette>=0.47.2", # CVE-2025-54121 "starlette>=0.49.1", # GHSA-7f5h-v6xp-fcq8 - "lxml>=6.0.2", # For python 3.14 pre-built wheels - "filelock>=3.20.1", # CVE-2025-68146 + "lxml>=6.1.0", # CVE-2026-41066 (Renovate #556); also required for python 3.14 pre-built wheels + "filelock>=3.20.3", # CVE-2025-68146 (>=3.20.1); CVE-2026-22701 (>=3.20.3, Renovate #387) "marshmallow>=3.26.2", # CVE-2025-68480 + "pygments>=2.20.0", # CVE-2026-4539 (>=2.20.0); transitive via rich + "cryptography>=46.0.7", # CVE-2026-39892 (>=46.0.7); transitive via pyjwt[crypto] + "pydicom>=3.0.2", # CVE-2026-32711 (>=3.0.2); transitive via dicomweb-client/wsidicom/highdicom + "pyasn1>=0.6.3", # CVE-2026-30922 (>=0.6.3); transitive via cryptography + "lxml-html-clean>=0.4.4", # CVE-2026-28348, CVE-2026-28350 (>=0.4.4); transitive via html-sanitizer + "python-multipart>=0.0.26", # CVE-2026-24486 (>=0.0.22), CVE-2026-40347 (>=0.0.26); transitive via fastapi/starlette + "protobuf>=6.33.5", # CVE-2026-0994 (>=6.33.5); transitive via google-cloud-storage/sentry-sdk ] [project.optional-dependencies] @@ -148,11 +155,12 @@ jupyter = [ # WARNING: one cannot negate or downgrade a dependency required here. use override-dependencies for that. "jupyter-core>=5.8.1", # CVE-2025-30167 "jupyterlab>=4.4.9", # CVE-2025-59842 + "nbconvert>=7.17.1", # CVE-2025-53000 (>=7.17.0, Dependabot #424); Dependabot #553 raised to 7.17.1 ] marimo = [ "cloudpathlib>=0.23.0,<1", "ipython>=9.8.0,<10", - "marimo>=0.18.4,<1", + "marimo>=0.23.0,<1", # GHSA-2679-6mx9-h9xc (Renovate #533) "matplotlib>=3.10.7,<4", "shapely>=2.1.0,<3", ] @@ -173,7 +181,7 @@ dev = [ "pip-licenses @ git+https://github.com/neXenio/pip-licenses.git@master", # https://github.com/raimon49/pip-licenses/pull/224 "pre-commit>=4.5.0,<5", "pyright>=1.1.408,<1.1.409", # Regression in 1.1.407, see https://github.com/microsoft/pyright/issues/11060 - "pytest>=9.0.2,<10", + "pytest>=9.0.3,<10", # CVE-2025-71176 requires >=9.0.3 (Renovate #538) "pytest-asyncio>=1.3.0,<2", "pytest-cov>=7.0.0,<8", "pytest-docker>=3.2.5,<4", @@ -207,13 +215,14 @@ dev = [ "watchdog>=6.0.0,<7", # Transitive overrides # WARNING: one cannot negate or downgrade a dependency required here. use override-dependencies for that. - "pip>=5.3", # CVE-2025-8869 - "uv>=0.9.7", # CVE-2025-54368, GHSA-w476-p2h3-79g9, GHSA-pqhf-p39g-3x64 + "pip>=25.3", # CVE-2025-8869 (>=25.3). CVE-2026-3219 (fix in 26.1, unreleased) accepted via --ignore-vuln; see SUPPLY_CHAIN_VULNERABILITIES.md. + "uv>=0.11.6", # CVE-2025-54368, GHSA-w476-p2h3-79g9, GHSA-pqhf-p39g-3x64 (>=0.9.7); GHSA-pjjw-68hj-v9mw (>=0.11.6, Renovate #536) "fonttools>=4.60.2", # CVE-2025-66034 (GHSA-768j-98cg-p3fv), dep of matplotlib + "virtualenv>=20.36.1", # pypa/virtualenv#3013 TOCTOU in app_data/lock dir; bundles filelock>=3.20.1 for CVE-2025-68146; transitive via nox/pre-commit ] [tool.uv] -required-version = ">=0.9.7" # CVE-2025-54368, GHSA-w476-p2h3-79g9, GHSA-pqhf-p39g-3x64 +required-version = ">=0.11.6" # CVE-2025-54368, GHSA-w476-p2h3-79g9, GHSA-pqhf-p39g-3x64, GHSA-pjjw-68hj-v9mw # WARNING: override-dependencies is *not* respected by uvx override-dependencies = [ # https://github.com/astral-sh/uv/issues/4422 "pytest>=9.0.1", # pytest-md-report depends on pytest<9 unnecessarily diff --git a/uv.lock b/uv.lock index 317f24a31..a0f806f6d 100644 --- a/uv.lock +++ b/uv.lock @@ -32,6 +32,7 @@ dependencies = [ { name = "boto3" }, { name = "certifi" }, { name = "crc32c" }, + { name = "cryptography" }, { name = "defusedxml" }, { name = "dicom-validator" }, { name = "dicomweb-client", extra = ["gcp"] }, @@ -52,6 +53,7 @@ dependencies = [ { name = "jsonschema", extra = ["format-nongpl"] }, { name = "loguru" }, { name = "lxml" }, + { name = "lxml-html-clean" }, { name = "marshmallow" }, { name = "nicegui", extra = ["native"] }, { name = "openslide-bin" }, @@ -61,11 +63,16 @@ dependencies = [ { name = "pillow" }, { name = "platformdirs" }, { name = "procrastinate" }, + { name = "protobuf" }, { name = "psutil" }, { name = "pyarrow", marker = "python_full_version >= '3.14'" }, + { name = "pyasn1" }, { name = "pydantic-settings" }, + { name = "pydicom" }, + { name = "pygments" }, { name = "pyjwt", extra = ["crypto"] }, { name = "python-dateutil" }, + { name = "python-multipart" }, { name = "pywin32", marker = "sys_platform == 'win32'" }, { name = "pyyaml" }, { name = "requests" }, @@ -90,6 +97,7 @@ jupyter = [ { name = "jupyter" }, { name = "jupyter-core" }, { name = "jupyterlab" }, + { name = "nbconvert" }, ] marimo = [ { name = "cloudpathlib" }, @@ -152,16 +160,18 @@ dev = [ { name = "types-pyyaml" }, { name = "types-requests" }, { name = "uv" }, + { name = "virtualenv" }, { name = "watchdog" }, ] [package.metadata] requires-dist = [ - { name = "aiohttp", specifier = ">=3.13.3" }, + { name = "aiohttp", specifier = ">=3.13.4" }, { name = "boto3", specifier = ">=1.42.4,<2" }, { name = "certifi", specifier = ">=2025.11.12" }, { name = "cloudpathlib", marker = "extra == 'marimo'", specifier = ">=0.23.0,<1" }, { name = "crc32c", specifier = ">=2.8,<3" }, + { name = "cryptography", specifier = ">=46.0.7" }, { name = "defusedxml", specifier = ">=0.7.1" }, { name = "dicom-validator", specifier = ">=0.7.3,<1" }, { name = "dicomweb-client", extras = ["gcp"], specifier = ">=0.59.3,<1" }, @@ -169,7 +179,7 @@ requires-dist = [ { name = "fastapi", extras = ["all", "standard"], specifier = ">=0.123.10" }, { name = "fastmcp", specifier = ">=3.2.0,<4" }, { name = "fastparquet", marker = "python_full_version < '3.14'", specifier = ">=2025.12.0,<2026.0.0" }, - { name = "filelock", specifier = ">=3.20.1" }, + { name = "filelock", specifier = ">=3.20.3" }, { name = "google-cloud-storage", specifier = ">=3.6.0,<4" }, { name = "h11", specifier = ">=0.16.0" }, { name = "highdicom", marker = "python_full_version < '3.14'", specifier = ">=0.26.1,<1" }, @@ -185,25 +195,32 @@ requires-dist = [ { name = "jupyter-core", marker = "extra == 'jupyter'", specifier = ">=5.8.1" }, { name = "jupyterlab", marker = "extra == 'jupyter'", specifier = ">=4.4.9" }, { name = "loguru", specifier = ">=0.7.3,<1" }, - { name = "lxml", specifier = ">=6.0.2" }, - { name = "marimo", marker = "extra == 'marimo'", specifier = ">=0.18.4,<1" }, + { name = "lxml", specifier = ">=6.1.0" }, + { name = "lxml-html-clean", specifier = ">=0.4.4" }, + { name = "marimo", marker = "extra == 'marimo'", specifier = ">=0.23.0,<1" }, { name = "marshmallow", specifier = ">=3.26.2" }, { name = "matplotlib", marker = "extra == 'marimo'", specifier = ">=3.10.7,<4" }, - { name = "nicegui", extras = ["native"], specifier = ">=3.5.0,<4" }, + { name = "nbconvert", marker = "extra == 'jupyter'", specifier = ">=7.17.1" }, + { name = "nicegui", extras = ["native"], specifier = ">=3.9.0,<4" }, { name = "openslide-bin", specifier = ">=4.0.0.10,<5" }, { name = "openslide-python", specifier = ">=1.4.3,<2" }, { name = "packaging", specifier = ">=26,<27" }, { name = "pandas", specifier = ">=2.3.3,<3" }, - { name = "pillow", specifier = ">=11.3.0" }, + { name = "pillow", specifier = ">=12.2.0" }, { name = "platformdirs", specifier = ">=4.3.2,<5" }, { name = "platformdirs", specifier = ">=4.5.1,<5" }, { name = "procrastinate", specifier = ">=3.5.3" }, + { name = "protobuf", specifier = ">=6.33.5" }, { name = "psutil", specifier = ">=7.1.3,<8" }, { name = "pyarrow", marker = "python_full_version >= '3.14'", specifier = ">=22.0.0,<23" }, + { name = "pyasn1", specifier = ">=0.6.3" }, { name = "pydantic-settings", specifier = ">=2.12.0,<3" }, + { name = "pydicom", specifier = ">=3.0.2" }, + { name = "pygments", specifier = ">=2.20.0" }, { name = "pyinstaller", marker = "extra == 'pyinstaller'", specifier = ">=6.14.0,<7" }, - { name = "pyjwt", extras = ["crypto"], specifier = ">=2.10.1,<3" }, + { name = "pyjwt", extras = ["crypto"], specifier = ">=2.12.0,<3" }, { name = "python-dateutil", specifier = ">=2.9.0.post0,<3" }, + { name = "python-multipart", specifier = ">=0.0.26" }, { name = "pywin32", marker = "sys_platform == 'win32'", specifier = ">=311,<312" }, { name = "pyyaml", specifier = ">=6.0.3,<7" }, { name = "requests", specifier = ">=2.33.0,<3" }, @@ -217,7 +234,7 @@ requires-dist = [ { name = "starlette", specifier = ">=0.47.2" }, { name = "starlette", specifier = ">=0.49.1" }, { name = "tenacity", specifier = ">=9.1.2,<10" }, - { name = "tornado", specifier = ">=6.5.0" }, + { name = "tornado", specifier = ">=6.5.5" }, { name = "tqdm", specifier = ">=4.67.1,<5" }, { name = "truststore", specifier = ">=0.10.4,<1" }, { name = "typer", specifier = ">=0.20.0,<1" }, @@ -241,12 +258,12 @@ dev = [ { name = "mypy", specifier = ">=1.19.0,<2" }, { name = "myst-parser", specifier = ">=4.0.1,<5" }, { name = "nox", extras = ["uv"], specifier = ">=2025.11.12" }, - { name = "pip", specifier = ">=5.3" }, + { name = "pip", specifier = ">=25.3" }, { name = "pip-audit", specifier = ">=2.10.0,<3" }, { name = "pip-licenses", git = "https://github.com/neXenio/pip-licenses.git?rev=master" }, { name = "pre-commit", specifier = ">=4.5.0,<5" }, { name = "pyright", specifier = ">=1.1.408,<1.1.409" }, - { name = "pytest", specifier = ">=9.0.2,<10" }, + { name = "pytest", specifier = ">=9.0.3,<10" }, { name = "pytest-asyncio", specifier = ">=1.3.0,<2" }, { name = "pytest-cov", specifier = ">=7.0.0,<8" }, { name = "pytest-docker", specifier = ">=3.2.5,<4" }, @@ -276,7 +293,8 @@ dev = [ { name = "tomli", specifier = ">=2.3.0,<3" }, { name = "types-pyyaml", specifier = ">=6.0.12.20250915,<7" }, { name = "types-requests", specifier = ">=2.32.4.20250913,<3" }, - { name = "uv", specifier = ">=0.9.7" }, + { name = "uv", specifier = ">=0.11.6" }, + { name = "virtualenv", specifier = ">=20.36.1" }, { name = "watchdog", specifier = ">=6.0.0,<7" }, ]