Skip to content

fix(security): clear all open Dependabot and CodeQL alerts - #33

Draft
rishitank wants to merge 4 commits into
mainfrom
fix/security-alerts
Draft

rishitank wants to merge 4 commits into
mainfrom
fix/security-alerts

Conversation

@rishitank

Copy link
Copy Markdown
Owner

What

This PR clears all 65 open Dependabot alerts (1 critical, 33 high, 24 medium, 7 low, all in uv.lock) and the 2 open CodeQL alerts (#10, #9).

  • uv.lock: targeted upgrades only, via uv lock --upgrade-package anyio pillow cryptography pyasn1 pyjwt mcp starlette python-multipart urllib3 msgpack pip pydantic-settings idna python-dotenv pytest requests pygments click. Nothing else in the lock moved.
    • click 8.3.1 → 8.5.0 is included because pip-audit (the Security Audit job) flags PYSEC-2026-2132 against it, even though Dependabot has no alert for it.
  • pyproject.toml: raised the lower bounds of the direct dependencies that had alerts, so a fresh install can't resolve a vulnerable version:
    • mcp>=1.28.1,<2
    • pydantic-settings>=2.14.2
    • python-dotenv>=1.2.2
    • Pillow>=12.3.0
    • pytest>=9.0.3
  • Why mcp has an upper bound (<2): mcp 2.x is out (2.2.0). It removed mcp.server.fastmcp (FastMCP was renamed MCPServer), so server.py fails at import. I tried it: ModuleNotFoundError: No module named 'mcp.server.fastmcp'. This is mcp 2.x …. The old mcp>=1.9.0 range means anyone who installs animawatch from PyPI today gets mcp 2.x and a broken server, so the cap also fixes that. mcp 1.30.0 is the latest 1.x and includes every mcp security fix. Migrating to 2.x is a real piece of work, and Renovate will propose it as a major-upgrade PR for a human to review (see the Renovate PR).
  • CodeQL refactor: remove modules that don't fit core debugging use case #10 (py/incomplete-url-substring-sanitization, high) at tests/test_metrics.py:149. The test checked "https://test.com" in report. It now finds the report's URL: line, parses it with urllib.parse.urlparse, and asserts scheme == "https" and hostname == "test.com". That is also a stricter assertion than before.
  • CodeQL chore: release 0.3.1 #9 (py/unused-global-variable, note) at src/animawatch/models.py:143. I removed STRUCTURED_OUTPUT_SCHEMA. Nothing in the repo references it: vision.py prompts with its own JSON_OUTPUT_INSTRUCTION. The now-unused typing.Any import went with it.

Alert → fixed-version map

main has 65 open alerts. Every one is resolved by the locked version below; I checked this programmatically against each alert's first_patched_version.

Package Locked (before → after) Alerts fixed (number · severity · advisory · first patched)
anyio 4.12.1 → 4.15.1 #71 · medium · GHSA-5p39-cfhj-2xmp · ≥4.14.2
#72 · critical · GHSA-82r6-8w77-94w6 · ≥4.14.2
cryptography 46.0.4 → 50.0.1 #3 · high · GHSA-r6ph-v2qm-q3c2 · ≥46.0.5
#9 · low · GHSA-m959-cc7f-wv43 · ≥46.0.6
#11 · medium · GHSA-p423-j2cm-9vmq · ≥46.0.7
#40 · high · GHSA-537c-gmf6-5ccf · ≥48.0.1
#65 · high · GHSA-g6cj-pr64-35w5 · ≥50.0.0
#73 · medium · GHSA-m2h6-j472-rp4c · ≥49.0.0
#74 · high · GHSA-jwv3-5hgf-82ww · ≥49.0.0
idna 3.11 → 3.20 #25 · medium · GHSA-65pc-fj4g-8rjx · ≥3.15
mcp (direct, bound raised) 1.26.0 → 1.30.0 #44 · high · GHSA-hvrp-rf83-w775 · ≥1.27.2
#45 · high · GHSA-jpw9-pfvf-9f58 · ≥1.27.2
#46 · high · GHSA-vj7q-gjh5-988w · ≥1.28.1
msgpack 1.1.2 → 1.2.2 #42 · high · GHSA-6v7p-g79w-8964 · ≥1.2.1
pillow (direct, bound raised) 12.1.0 → 12.3.0 #4 · high · GHSA-cfh3-3jmp-rvhc · ≥12.1.1
#12 · high · GHSA-whj4-6x5x-4v2j · ≥12.2.0
#17 · medium · GHSA-5xmw-vc9v-4wf2 · ≥12.2.0
#18 · high · GHSA-pwv6-vv43-88gr · ≥12.2.0
#19 · medium · GHSA-wjx4-4jcj-g98j · ≥12.2.0
#20 · medium · GHSA-r73j-pqj5-w3x7 · ≥12.2.0
#47 · medium · GHSA-pg7v-jwj7-p798 · ≥12.3.0
#48 · high · GHSA-62p4-gmf7-7g93 · ≥12.3.0
#49 · high · GHSA-5x94-69rx-g8h2 · ≥12.3.0
#50 · high · GHSA-8v84-f9pq-wr9x · ≥12.3.0
#51 · high · GHSA-45hq-cxwh-f6vc · ≥12.3.0
#52 · high · GHSA-phj9-mv4w-65pm · ≥12.3.0
#53 · medium · GHSA-4x4j-2g7c-83w6 · ≥12.3.0
#54 · high · GHSA-6r8x-57c9-28j4 · ≥12.3.0
#55 · high · GHSA-xj96-63gp-2gmr · ≥12.3.0
#56 · high · GHSA-9hw9-ch79-4vh6 · ≥12.3.0
#57 · high · GHSA-vjc4-5qp5-m44j · ≥12.3.0
#58 · medium · GHSA-fj7v-r99m-22gq · ≥12.3.0
#59 · high · GHSA-jjj6-mw9f-p565 · ≥12.3.0
pip 26.0 → 26.2.1 #16 · medium · GHSA-58qw-9mgm-455v · ≥26.1
#21 · medium · GHSA-jp4c-xjxw-mgf9 · ≥26.1
#43 · medium · GHSA-wf93-45jw-7689 · ≥26.1.2
#68 · medium · GHSA-qwm4-qh6w-59xr · ≥26.2.0
pyasn1 0.6.2 → 0.6.4 #6 · high · GHSA-jr27-m4p2-rc6r · ≥0.6.3
#60 · high · GHSA-hm4w-wwcw-mr6r · ≥0.6.4
#61 · high · GHSA-8ppf-4f7h-5ppj · ≥0.6.4
#64 · high · GHSA-m4p7-r5rc-7g4j · ≥0.6.4
pydantic-settings (direct, bound raised) 2.12.0 → 2.15.0 #41 · medium · GHSA-4xgf-cpjx-pc3j · ≥2.14.2
pygments 2.19.2 → 2.21.0 #10 · low · GHSA-5239-wwwm-4pmq · ≥2.20.0
pyjwt 2.11.0 → 2.15.0 #5 · high · GHSA-752w-5fwx-jx9f · ≥2.12.0
#28 · medium · GHSA-jq35-7prp-9v3f · ≥2.13.0
#29 · medium · GHSA-w7vc-732c-9m39 · ≥2.13.0
#31 · high · GHSA-xgmm-8j9v-c9wx · ≥2.13.0
#62 · low · GHSA-fhv5-28vv-h8m8 · ≥2.13.0
#63 · medium · GHSA-993g-76c3-p5m4 · ≥2.13.0
pytest (direct, bound raised) 9.0.2 → 9.1.1 #13 · medium · GHSA-6w46-j5rx-g56g · ≥9.0.3
python-dotenv (direct, bound raised) 1.2.1 → 1.2.3 #15 · medium · GHSA-mf9w-mj56-hr94 · ≥1.2.2
python-multipart 0.0.22 → 0.0.32 #14 · medium · GHSA-mj87-hwqh-73pj · ≥0.0.26
#22 · high · GHSA-pp6c-gr5w-3c5g · ≥0.0.27
#32 · low · GHSA-vffw-93wf-4j4q · ≥0.0.30
#33 · low · GHSA-6jv3-5f52-599m · ≥0.0.30
#34 · low · GHSA-v9pg-7xvm-68hf · ≥0.0.31
#35 · high · GHSA-5rvq-cxj2-64vf · ≥0.0.30
requests 2.32.5 → 2.34.2 #8 · medium · GHSA-gc5v-m9x4-r6x2 · ≥2.33.0
starlette 0.52.1 → 1.7.0 #26 · medium · GHSA-86qp-5c8j-p5mr · ≥1.0.1
#36 · medium · GHSA-x746-7m8f-x49c · ≥1.1.0
#37 · high · GHSA-wqp7-x3pw-xc5r · ≥1.1.0
#38 · low · GHSA-jp82-jpqv-5vv3 · ≥1.3.0
#39 · high · GHSA-82w8-qh3p-5jfq · ≥1.3.1
urllib3 2.6.3 → 2.8.0 #23 · high · GHSA-mf9v-mfxr-j63j · ≥2.7.0
#24 · high · GHSA-qccp-gfcp-xxvc · ≥2.7.0

(Alert #2, protobuf, is already fixed: protobuf left the lock in #4.)

How it was verified

All of this was run locally with uv 0.8.17 on Python 3.12, the version CI uses, on the final lock (which is byte-for-byte what the relock workflow committed):

  • uv sync --all-extras --dev --locked: OK
  • uv run pytest: 149 passed
  • uv run ruff check . and uv run ruff format --check .: clean
  • uv run mypy src/: no issues in 16 files
  • uv run pip-audit: No known vulnerabilities found (on main it reports click PYSEC-2026-2132)
  • A script compared every open alert's first_patched_version with the locked version: 0 still vulnerable.

uv.lock is around 330 KB, too big for an API push. A temporary workflow (zz-tmp-uv-lock.yml, pinned to uv 0.8.17) ran the same uv lock --upgrade-package … command on this branch and committed only uv.lock as github-actions[bot] (8eac26c). The workflow was then deleted by an ordinary commit (b80a921), so CI runs on the final head.

Risks

  • starlette 0.52 → 1.7 is a major version, pulled in transitively by mcp 1.30. The tests pass, but no test covers the --http (streamable-http) transport end to end. I started animawatch --http: the server boots and answers POST /mcp initialize with 200. The session then fails on Playwright's browser launch, because the sandbox has no Chromium build that matches, and main fails the same way. So please give --http a quick manual check.
  • cryptography 46 → 50 and pyjwt 2.11 → 2.15 are transitive (via mcp / google-auth) and aren't used directly.
  • Pillow 12.3 deprecates Image.getdata(). diff.py still calls it, which is where the 11 DeprecationWarnings come from. It is removed only in Pillow 14 (2027-10). feat: improvements for PyPI publishing and testing #13 already replaces it with tobytes(), which behaves the same on 10.x through 12.3, so the two PRs are consistent and will merge cleanly in either order.
  • Removing STRUCTURED_OUTPUT_SCHEMA is technically a public-name removal in a 0.x package. Nothing in the repo used it.

What Rishi must do

  • Review and merge. This is opened as a draft on purpose: marking it ready triggers auto-merge.yml, which enables auto-merge with your PAT, and merging is your call.
  • After it merges, the alerts close automatically on the next dependency-graph and CodeQL scan of main.

🤖 Generated with Claude Code

https://claude.ai/code/session_0171XyyqTUH64gAi1AcerwjN

rishitank and others added 3 commits September 25, 2026 15:08
- pyproject: mcp>=1.28.1,<2 (mcp 2.x removed mcp.server.fastmcp, so an
  uncapped range installs a breaking major), pydantic-settings>=2.14.2,
  python-dotenv>=1.2.2, Pillow>=12.3.0, pytest>=9.0.3.
- CodeQL #10 (py/incomplete-url-substring-sanitization): parse the URL
  line of the metrics report and compare scheme and hostname instead of a
  substring check.
- CodeQL #9 (py/unused-global-variable): remove the dead
  STRUCTURED_OUTPUT_SCHEMA constant; vision.py prompts with its own
  JSON_OUTPUT_INSTRUCTION and nothing references it.
- Temporary workflow regenerates uv.lock (too large for the API push).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0171XyyqTUH64gAi1AcerwjN
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0171XyyqTUH64gAi1AcerwjN
@rishitank

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: rishitank/animawatch/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 2f196788-be38-45b5-be0a-c868b827ca7b

📥 Commits

Reviewing files that changed from the base of the PR and between b80a921 and 86ead7f.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • src/animawatch/models.py
  • tests/test_metrics.py
💤 Files with no reviewable changes (1)
  • src/animawatch/models.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


Summary by CodeRabbit

  • Changes
    • Removed access to the exported structured-output schema.
  • Tests
    • Strengthened report-generation checks to confirm that reported URLs use HTTPS and point to the expected hostname.

Walkthrough

The pull request raises minimum versions for five dependencies, removes STRUCTURED_OUTPUT_SCHEMA and its unused import, and strengthens a metrics test to check the reported URL’s scheme and hostname.

Changes

Dependency minimums

Layer / File(s) Summary
Dependency constraints
pyproject.toml
Minimum versions are raised for mcp, pydantic-settings, python-dotenv, Pillow and pytest. Other dependency constraints remain unchanged.

Model schema removal

Layer / File(s) Summary
Remove schema variable
src/animawatch/models.py
The Any import and STRUCTURED_OUTPUT_SCHEMA variable are removed.

Metrics URL assertion

Layer / File(s) Summary
Parse and check reported URL
tests/test_metrics.py
The test checks that exactly one URL: line exists and that its URL has the https scheme and test.com hostname.

Priority: ⬆️ High

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 86ead

The dependency lock matches the updated requirements, and the schema and metrics changes have no identified contract break. No concrete change-specific merge risk is established.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 86ead

The dependency limits appear intended to keep installations on a compatible, updated MCP release. No new production access path was identified, but installed versions and downstream use of the removed schema export have not been verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The examined production-facing effect is dependency selection for the existing MCP server, not a new server tool or an expanded caller path. Installed dependency versions remain unverified.

Trust Boundaries and Controls

  • inferred — Parsing a URL in this test does not add a production trust-boundary check: the unchanged producer formats the supplied URL into the report.

Resilience and Maintainability Implications

  • inferred — The MCP major-version cap limits fresh resolution away from a major release whose compatibility with the server’s existing import is not demonstrated; it does not itself prove the resolved installation is vulnerability-free.

Hardening Proposals

  • proposed — Verify the versions selected by locked and deployed installations before relying on the new minimums as evidence that dependency alerts are cleared.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main security change: clearing Dependabot and CodeQL alerts through dependency updates and code fixes.
Description check ✅ Passed The description is directly related to the changeset. It explains the dependency upgrades, CodeQL fixes, verification results, risks, and required follow-up.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Apprentice, versions rise in line
A schema fades from sight
One URL is parsed and checked
Its host and scheme burn bright
The Dark Side keeps the test precise

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@rishitank

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@rishitank

Copy link
Copy Markdown
Owner Author

Brought up to date with main using Update branch. The new head is 86ead7f.

This PR stays a draft until #32 (which fences auto-merge.yml) is merged.

🤖 Generated with Claude Code

@rishitank

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@rishitank

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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