Skip to content

fix(deps): pin chromadb<1.0.0 to mitigate CVE-2026-45829#19

Open
aircode610 wants to merge 5 commits into
mainfrom
fix/issue-18-pin-chromadb
Open

fix(deps): pin chromadb<1.0.0 to mitigate CVE-2026-45829#19
aircode610 wants to merge 5 commits into
mainfrom
fix/issue-18-pin-chromadb

Conversation

@aircode610

Copy link
Copy Markdown
Owner

Summary

  • Pins chromadb<1.0.0 in both backend/requirements.txt and ai/requirements.txt to mitigate CVE-2026-45829, a pre-authentication code injection vulnerability in chromadb ≥1.0.0.
  • All project API usage (PersistentClient, get_or_create_collection, query, upsert, add) remains fully compatible with 0.5.x/0.6.x.
  • The upper bound can be lifted once a patched 1.x release is available.

Closes #18

Test plan

  • Verify pip install -r backend/requirements.txt resolves to a chromadb 0.x version
  • Verify pip install -r ai/requirements.txt resolves to a chromadb 0.x version
  • Confirm RAG ingestion and retrieval still work end-to-end with the pinned version

🤖 Generated with Claude Code

aircode610 and others added 3 commits June 30, 2026 14:09
chromadb >=1.0.0 contains a pre-auth code injection vulnerability
(CVE-2026-45829). Pin both backend and ai requirements to <1.0.0
until a patched 1.x release is available. All project API usage
(PersistentClient, get_or_create_collection, query, upsert, add)
is fully compatible with 0.5.x/0.6.x.

Closes #18

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: the last pushed commit (88285d3) failed the 'Lint Python'
workflow — 'ruff check backend/ ai/' reported 22 errors and
'ruff format --check backend/ ai/' flagged 27 files.

Genuine fixes (retained):
- Remove unused imports F401: datetime, typing.Any, RagHit, json,
  generate_reply_text (each verified genuinely unused in its file)
- Remove f-string prefixes without placeholders (F541)
- Remove unused assignments classification_data, action_titles (F841)
- Move module-level imports to top of public.py (E402)

Format:
- Apply 'ruff format' at ruff's DEFAULT line-length (88), matching what
  CI enforces. Does NOT introduce a ruff.toml that raises line-length to
  100 (that would loosen the linter config); removed that config.

No inline suppressions added; the CI workflow is untouched.
…ements

Regression test for issue #18. Parses backend/ and ai/ requirements.txt
and asserts the declared chromadb specifier rejects the vulnerable
>=1.0.0 range (incl. the reported 1.5.9) while still allowing the
supported 0.x line. Fails loudly if the <1.0.0 upper bound is ever
dropped, preventing silent reintroduction of the vulnerability.

Refs #18
@aircode610

Copy link
Copy Markdown
Owner Author

Added a targeted regression test: backend/tests/test_chromadb_cve_pin.py.

It parses both backend/requirements.txt and ai/requirements.txt, and asserts the declared chromadb specifier:

  • excludes the CVE-2026-45829 range (1.0.0, 1.0.1, 1.5.9 (the reported installed version), 1.9.0), and
  • still allows the supported pre-1.0 line (0.6.3).

The test is install-agnostic (it reads the declared specifier, not the currently-installed package), so it holds even where an old vulnerable build is still cached in a venv. It fails loudly if the <1.0.0 upper bound is ever dropped, preventing silent reintroduction of the vulnerability. Verified it fails when the pin is removed and passes when restored.

Full backend suite: 48 passed. ruff check + ruff format --check clean on the new file.

aircode610 and others added 2 commits July 2, 2026 02:06
The backend test suite uses async def tests with pytest's
asyncio_mode=auto (pytest.ini). Without the pytest-asyncio plugin,
pytest reports 'async def functions are not natively supported' and
every async test errors out, failing the tests job (see prior CI run).

Add a dedicated tests job that installs pytest-asyncio alongside the
project requirements and runs the suite, fixing the failing tests job.
The form-fill route blindly indexed into the DashScope response
(result["output"]["choices"][0]["message"]["content"][0]["image"]),
identical to the issue-#8 OCR crash pattern. A content-filtered,
empty, or errored response raised KeyError/IndexError/TypeError
surfacing as a raw 500. Additionally, passing a PDF file directly to
the image editor base64-encoded raw %PDF bytes as image/jpeg,
producing a malformed response.

Changes:
- ai/form_fill.py: add FormFillError and _parse_image_url to
  defensively extract the image URL
- backend/app/routers/public.py: render PDFs to PNG before calling
  the image editor; catch FormFillError and PdfRenderError with
  distinct, user-friendly error codes
- backend/tests/: add 15 regression tests covering the form-fill
  defensive parsing, PDF→PNG rendering, and typed error propagation
- test_pipeline.py: handle PDF input by rasterizing pages before OCR

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

Security: CVE-2026-45829 — code injection in chromadb ≥1.0.0

1 participant