Skip to content

chore(security): clear 12 advisories in langchain/uv.lock (h11, idna, orjson, requests, urllib3, pytest) - #10

Open
benfrank241 wants to merge 1 commit into
mainfrom
chore/security-daily-20260902-integrations-python-uv-langchain
Open

chore(security): clear 12 advisories in langchain/uv.lock (h11, idna, orjson, requests, urllib3, pytest)#10
benfrank241 wants to merge 1 commit into
mainfrom
chore/security-daily-20260902-integrations-python-uv-langchain

Conversation

@benfrank241

Copy link
Copy Markdown
Member

Security: 12 advisories cleared in langchain/uv.lock (lockfile-only)

Why this is a hand-authored branch, not a Dependabot PR

Dependabot alerts are not running on this repo. GET /repos/vectorize-io/integrations-python/dependabot/alerts returns HTTP 200 with an empty array for every state (open, fixed, dismissed, auto_dismissed) despite a committed langchain/uv.lock — i.e. the repo has never been scanned. There are therefore no alert numbers to reference; the advisory set below came from a local audit:

uv export --frozen --no-emit-project --format requirements-txt -o req.txt
uvx pip-audit -r req.txt --no-deps

Baseline (main, py3.13 resolution): 23 findings across 8 packages.

Recommendation: enable Dependabot alerts under Settings -> Code security. This repo is currently invisible to it.

Changes — langchain/uv.lock only

pyproject.toml is not modified. Every bump is a scoped lock regeneration:

uv lock --upgrade-package urllib3 --upgrade-package requests --upgrade-package idna \
        --upgrade-package orjson --upgrade-package h11 --upgrade-package httpcore \
        --upgrade-package pytest

The lock resolves two legs because requires-python = ">=3.9", so two versions appear for some packages:

package py>=3.10 py3.9 advisories cleared
h11 0.14.0 -> 0.16.0 same GHSA-vqfr-h8mv-ghfj (CVE-2025-43859)
idna 3.10 -> 3.19 same GHSA-65pc-fj4g-8rjx (CVE-2026-45409)
orjson 3.10.15 -> 3.12.0 3.11.5 GHSA-hx9q-6w63-j58v (CVE-2025-67221)
requests 2.32.3 -> 2.34.2 2.32.5 GHSA-9hjg-9r4m-mvj7 (CVE-2024-47081), GHSA-gc5v-m9x4-r6x2 (CVE-2026-25645)
urllib3 2.3.0 -> 2.7.0 2.6.3 GHSA-qccp-gfcp-xxvc, GHSA-pq67-6m6q-mj2v, GHSA-gm62-xv2j-4w53, GHSA-48p4-8xcf-vxj5, GHSA-2xpw-w6gg-jr37, GHSA-38jv-5279-wg99
pytest (dev) 8.3.5 -> 9.1.1 8.4.2 GHSA-6w46-j5rx-g56g (CVE-2025-71176)

Two supporting bumps carry no advisory of their own:

  • httpcore 1.0.7 -> 1.0.9 — required. httpcore 1.0.7 declares h11<0.15, which pinned h11 at 0.14.0; h11 could not move without it.
  • pygments 2.21.0 added — new transitive dependency of pytest 9.

⚠️ Needs a human eye

  • pytest 8 -> 9 is a major bump (dev dependency only, py>=3.10 leg). Test collection succeeds on 3.9 and 3.13; the live integration tests could not be run locally (see below).

What this does NOT fix

langchain-core (6 advisories) and langsmith (3) are deliberately excluded — clearing them requires langchain-core 1.x, a major bump of this package's primary dependency that pulls in 13 new transitive packages. It is proposed separately so it can be reviewed on its own merits.

Residual on the Python 3.9 leg (requires-python = ">=3.9" caps what is installable, because every fix below dropped 3.9):

package py3.9 best still open fix needs
urllib3 2.6.3 GHSA-qccp-gfcp-xxvc (CVE-2026-44431) 2.7.0 (py>=3.10)
urllib3 2.6.3 GHSA-mf9v-mfxr-j63j (CVE-2026-44432) 2.7.0 (py>=3.10)
requests 2.32.5 GHSA-gc5v-m9x4-r6x2 2.33.0 (py>=3.10)
orjson 3.11.5 GHSA-hx9q-6w63-j58v 3.11.6 (py>=3.10)
pytest 8.4.2 GHSA-6w46-j5rx-g56g 9.0.3 (py>=3.10)

Note honestly: GHSA-mf9v-mfxr-j63j is newly introduced on the 3.9 leg — it was introduced in urllib3 2.6.0 and fixed in 2.7.0, and 2.6.3 is the newest urllib3 that still supports 3.9. Net for the 3.9 leg is still strongly positive (8 cleared, 1 introduced); on py3.10-3.13 all 12 are cleared with nothing introduced.

The real fix for the residual is dropping Python 3.9, which has been EOL since October 2025. Removing it from requires-python, the classifiers and the CI matrix collapses both resolution legs into one and clears every advisory in this table. That is a maintainer decision, so it is not attempted here.

Verification (run locally on both ends of the CI matrix)

Commands derived from .github/workflows/python_test.yml and lint.yml, run under langchain/ on Python 3.9 and 3.13:

step py3.9 py3.13
uv sync --dev pass pass
uv run ruff format --check pass pass
uv run ruff check pass pass
uv run mypy . pass pass
uv run pytest tests (collection) 2 collected 2 collected
uv run pytest tests (execution) not runnable locally not runnable locally

tests/test_retrievers.py is a live integration suite: its session fixture raises ValueError: Please set the VECTORIZE_TOKEN environment variable. This fails identically on unmodified main — it is environmental, not a regression from this change. Actual execution is what this PR's own CI run provides, which is the reason for opening a hand-authored branch at all (Dependabot's branches do not receive repository secrets).

Post-change audit: py3.13 leg 23 -> 9 findings, py3.9 leg 23 -> 11; every remaining finding is langchain-core/langsmith or a 3.9-cap listed above.


Opened by the daily security sweep. Not to be merged automatically - please review.

… langchain/uv.lock

Lockfile-only scoped regeneration (uv lock --upgrade-package ...) clearing 12
advisories found by a local pip-audit run. No pyproject.toml constraint changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@benfrank241

Copy link
Copy Markdown
Member Author

CI triage: both red checks are pre-existing and unrelated to this change

CI is red, but neither failure is caused by anything in this PR. Both reproduce with the dependency versions this branch does not touch, and both hit PR #10 and PR #11 identically. Evidence below so a reviewer does not have to re-derive it.

1. LangChain Unit Tests (all 5 matrix legs) — HTTP 402 from the Vectorize API

vectorize_client.exceptions.ApiException: (402)
Reason: Payment Required
HTTP response body: {"success":false,"error":"Upgrade Required",
  "message":"API access is available on paid plans only. Please upgrade to use this endpoint.",
  "code":"UPGRADE_REQUIRED"}
.venv/lib/python3.13/site-packages/vectorize_client/exceptions.py:162: ApiException
  • It is an ERROR at setup, not a test assertion — it happens in the session-scoped fixture in tests/test_retrievers.py, before any code under test runs.
  • The secrets are present and valid: a missing/invalid VECTORIZE_TOKEN returns 401, and locally without the secret the fixture raises ValueError: Please set the VECTORIZE_TOKEN environment variable. Getting a 402 means it authenticated and was rejected on plan/billing, not credentials.
  • Identical on py3.9 and py3.13, i.e. on both resolution legs of the lock — so it is independent of which package versions resolved.
  • Action for a maintainer: the Vectorize account backing VECTORIZE_TOKEN needs API access restored on its plan. Until then this workflow cannot pass on any branch.

2. Lint LangChain (both legs) — pydantic-core 2.27.2 fails to build on Python 3.14

PYO3_ENVIRONMENT_SIGNATURE="cpython-3.14-64bit"
Error: command ['maturin', 'pep517', 'build-wheel', ...] returned non-zero exit status 1
hint: `pydantic-core` (v2.27.2) was included because `langchain-vectorize` (v0.0.3)
      depends on `vectorize-client` (v0.4.0) which depends on `pydantic` (v2.10.6)
      which depends on `pydantic-core`

Root cause is a latent bug in .github/workflows/lint.yml. It declares a matrix:

strategy:
  matrix:
    python-version: ['3.9', '3.13']

but then never uses matrix.python-version:

- uses: actions/setup-python@v5
  with:
    python-version-file: "langchain/pyproject.toml"

setup-python reads requires-python = ">=3.9" from that file and resolves it to the newest interpreter available — the log shows Successfully set up CPython (3.14.7). So both matrix legs install 3.14 regardless of the matrix, and pydantic-core 2.27.2 publishes no cp314 wheel, so uv falls back to a maturin/pyo3 source build that fails.

This is environment drift, not a code change: this repo last ran CI on 2025-09-01, before 3.14 existed on the runners. pydantic 2.10.6 and pydantic-core 2.27.2 are byte-identical to main on this branch — the only lines touching them in the diff are upload-time metadata and resolution markers, no version change.

Two independent fixes, both out of scope for a security bundle (mixing an unrelated lockfile or workflow change into a security PR is exactly what these bundles avoid):

  • python-version: ${{ matrix.python-version }} in lint.yml, so the matrix is actually honoured; and/or
  • bump pydantic/pydantic-core so a cp314 wheel exists.

Tracked in #12.

On the lockfile diff size

The diff is large (~750 added / ~590 removed lines) relative to 8 version changes. That is re-resolution metadata: this uv adds an upload-time = field to every lock entry it re-resolves. Verified not to be hidden dependency churn — a no-op uv lock on untouched main produces a byte-identical lockfile (0 changed lines), and the only version = lines in this diff are the packages named in the PR description.

What was verified locally

uv sync --dev, ruff format --check, ruff check, mypy . and pytest collection all pass on both py3.9 and py3.13. Test execution is impossible locally (and now, per #1 above, in CI too) because the suite is a live integration suite against a paid API.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant