Skip to content

chore(deps): bump Brotli to 1.2.1 for CVE-2026-111497 - #635

Open
amrit110 wants to merge 4 commits into
mainfrom
chore/brotli-cve-2026-111497
Open

amrit110 wants to merge 4 commits into
mainfrom
chore/brotli-cve-2026-111497

Conversation

@amrit110

@amrit110 amrit110 commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Why

CVE-2026-111497 is an out-of-bounds write in the Brotli decoder that allows remote code execution through a crafted br-compressed stream. The PyPI Brotli package up to 1.2.0 and brotlicffi 1.2.0.x carry the same decoder. Both are fixed in Brotli 1.2.1 and brotlicffi 1.2.1.0. (Node.js is affected too, but this repo has no Node version pins, so this PR only covers the Python packages.)

What changed

  • uv.lock: brotli 1.2.0 to 1.2.1, brotlicffi 1.2.0.1 to 1.2.1.0, via uv lock --upgrade-package brotli --upgrade-package brotlicffi with uv 0.9.11 (the version CI pins). No other packages changed.
  • uv 0.9.11 also rewrote the lock header: revision = 2 to revision = 3, and requires-python normalized from ">=3.10.0, <3.11" to "==3.10.*" (same meaning). uv 0.7.20 produced the same requires-python change, so it is uv normalization, not a constraint change.
  • brotli comes in only through py7zr in the llm dependency group (brotli on CPython, brotlicffi on PyPy).

How I verified it

  • uv lock --locked (uv 0.9.11): passes.
  • uv sync --locked (uv 0.9.11), default groups plus docs/test/dev: passes. brotli is not in those groups, so I then installed the brotli entry from uv export --locked --group llm with --require-hashes into the synced env: python -c "import brotli; print(brotli.__version__)" prints 1.2.1.
  • pre-commit run --files uv.lock: all hooks pass, including uv-lock.
  • I did not run the test suite: the change only touches a transitive dependency of py7zr in the llm group, and the suite is heavy.

Deploy impact

No deploy on merge. docs.yml runs on push to main when uv.lock changes and rebuilds and pushes the docs site to GitHub Pages; that is the only publish step a merge triggers. PyPI publishing runs only on v* tags.

CI fix: pip-audit (second commit)

run-code-check failed at the pip-audit step, not because of this bump: pip-audit flagged 258 advisories in 26 packages that were published after the lockfile was last refreshed. main has the same lockfile apart from brotli, so it would fail the same way.

  • uv.lock: uv lock --upgrade-package ... (uv 0.9.11) for every flagged package. Packages that reached a fixed version include aiohttp 3.14.5, anyio 4.14.2, certifi 2026.10.23, gitpython 3.2.1, monai 1.6.1, msgpack 1.2.3, multidict 7.1.0, nltk 3.10.4, pip 26.2.2, pyasn1 0.6.4, setuptools 84.2.1, starlette 1.7.0, torch 2.14.1 (torchvision 0.29.1), tornado 6.5.10, urllib3 2.8.0, virtualenv 21.14.13, werkzeug 3.1.9. 32 packages changed in total; nothing was added or removed.
  • .github/workflows/static_code_checks.yaml: added the advisories that have no fix installable under this project's pins to ignore-vulns, with a comment explaining each group, following the existing entries:
    • cryptography (needs >=48) and protobuf (needs >=5.29.6): flwr 1.18 requires cryptography<45 and protobuf<5. Newer flwr requires Python 3.11+.
    • datasets (fixed in 5.0.1) and fsspec: the dev group pins datasets<3, flwr-datasets requires datasets<5, and datasets 2.x caps fsspec at 2024.6.1.
    • pillow (fixed in 13.0.0), filelock (4.2.1) and keras (3.13.2+): every fixed release requires Python 3.11+, and the project is pinned to Python 3.10.
    • transformers: fixes are only in 5.x, which this repo already defers, or there is no fix yet.

Clearing these for real means moving to Python 3.11+ and a newer flwr, which is a bigger change than this PR.

Verified locally, the same way CI does:

  • uv sync --group dev --group test --group codestyle (uv 0.9.11), then pip-audit 2.10.0 against .venv with the workflow's ignore list: "No known vulnerabilities found, 70 ignored".
  • uv run pre-commit run --all-files: every hook passes (including uv-lock, ruff, mypy, nbqa-mypy).
  • uv run pytest -m "not smoketest" tests: 475 passed, 33 deselected.

Smoke test metrics (third and fourth commits)

With the upgraded lock, test_apfl in the standard smoke tests failed on metric drift (round 2 val global accuracy, for example, moved from 0.72833 to 0.765). Every other standard smoke test passed unchanged. torch 2.12 to 2.14 is the likely cause, and the APFL values were last refreshed the same way after the May dependency upgrade (e72a0e6, 984b08a). This test is skipped locally ("Test doesn't work locally") and a forced local run gives different numbers on macOS, so I took the new values from the Linux CI runs: eval metrics from the first failing run, then client training metrics once those matched. Only tests/smoke_tests/apfl_server_metrics.json and apfl_client_metrics.json changed.

Still red: test_apfl is bimodal on CI. Across five runs on this branch with the same lock, APFL produced one of two sets of values: set A (runs 1 and 2, now in the JSON files; the server metrics matched on run 2) and set B (runs 3 to 5, for example round 1 val personal accuracy 0.53056 vs 0.52189, round 3 val local accuracy 0.65222 vs 0.81022). This looks like the same flakiness main already has: test_apfl failed the standard smoke tests on six recent runs (September and October) that did not touch torch (for example the gitpython, virtualenv and anyio Dependabot PRs and pre-commit-ci-update-config). Fail-fast then cancels the other groups, which otherwise pass. This needs a maintainer decision: investigate the nondeterminism, loosen the APFL tolerance, or accept a rerun that lands on set A.

pre-commit.ci

pre-commit.ci fails only on the uv-lock hook: it cannot download CPython 3.10.20 from GitHub ("dns error ... Temporary failure in name resolution"). It failed the same way on the original Brotli commit, before any of these changes, and again after a pre-commit.ci run re-trigger. The same hook passes in the GitHub Actions run-code-check job.

@codecov

codecov Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.16%. Comparing base (b43cbed) to head (c9679b6).

❗ There is a different number of reports uploaded between BASE (b43cbed) and HEAD (c9679b6). Click for more details.

HEAD has 6 uploads less than BASE
Flag BASE (b43cbed) HEAD (c9679b6)
11 5
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #635      +/-   ##
==========================================
- Coverage   79.71%   72.16%   -7.55%     
==========================================
  Files         166      166              
  Lines       10573    10573              
==========================================
- Hits         8428     7630     -798     
- Misses       2145     2943     +798     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

pip-audit was failing on advisories published since the lockfile was last
refreshed, unrelated to the Brotli bump. Upgrade every flagged package that
has a fix installable on Python 3.10 with flwr 1.18 (aiohttp, anyio, certifi,
gitpython, monai, msgpack, multidict, nltk, pip, pyasn1, setuptools,
starlette, torch, tornado, urllib3, virtualenv, werkzeug, and others).

Ignore the remaining advisories, which have no installable fix under the
project's pins (cryptography and protobuf capped by flwr, datasets and
fsspec capped by the datasets<3 pin and flwr-datasets, pillow, filelock and
keras fixes requiring Python 3.11+, transformers fixes only in 5.x or none).
@amrit110

Copy link
Copy Markdown
Member Author

pre-commit.ci run

The APFL smoke test is the only standard smoke test whose metrics moved
after the dependency upgrades (torch 2.12 to 2.14 is the likely cause).
Values are taken from the Linux CI run, since this test does not run
locally.
Second half of the APFL metric refresh: the client fit accuracies and
losses, taken from the Linux CI run once the eval metrics matched.

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.

1 participant