fix(security): Upgrade fastmcp to v3 to address CVE-2025-69872#2294
fix(security): Upgrade fastmcp to v3 to address CVE-2025-69872#2294
Conversation
This upgrade addresses Dependabot alert #44 by removing the diskcache dependency (vulnerable to unsafe pickle deserialization). Changes: - Update fastmcp requirement from >=2.11.3 to >=3.0.0 - fastmcp v3 uses py-key-value-aio[filetree] instead of [disk], which removes the diskcache dependency All 2429 SDK tests pass with the upgrade. Resolves: https://github.com/OpenHands/software-agent-sdk/security/dependabot/44 Co-authored-by: openhands <openhands@all-hands.dev>
API breakage checks (Griffe)Result: Failed Log excerpt (first 1000 characters) |
Agent server REST API breakage checks (OpenAPI)Result: Passed |
all-hands-bot
left a comment
There was a problem hiding this comment.
🟡 Acceptable - Security fix is necessary and pragmatic, but this needs eval verification before merge.
Key Concern: Major version bump (2.x → 3.x) with no visible code changes. Major versions signal breaking changes - where are the adaptations? Per repo guidelines, changes to SDK dependencies that could affect agent behavior should be flagged for lightweight eval testing.
Action Items:
- Run examples (see inline comment)
- Verify no direct imports of removed transitive deps
- Run lightweight evals to catch behavioral changes tests might miss
Verdict: Security fix is good, approach is sound, but flag for human maintainer to verify with evals before merge.
|
On my local openhands repo, I pointed https://github.com/OpenHands/OpenHands/blob/main/openhands/app_server/sandbox/sandbox_spec_service.py#L16 to the python arm64 agent server image built in this PR https://github.com/OpenHands/software-agent-sdk/actions/runs/22659801479/job/65677208258?pr=2294. Public Deepwiki MCP server has already been configured:
|
all-hands-bot
left a comment
There was a problem hiding this comment.
🟢 Good taste - Pragmatic security fix
Verdict: ✅ Approve and merge
This is a straightforward dependency upgrade to address CVE-2025-69872 (unsafe pickle deserialization in diskcache). The change is minimal, well-motivated, and properly vetted:
✅ Real security vulnerability addressed
✅ API compatibility confirmed (previous investigation in threads)
✅ All 2429 tests passing
✅ CI passing (pre-commit, sdk-tests, tools-tests, agent-server-tests)
✅ Lock file changes show clean removal of vulnerable dep
On the unresolved thread about examples: The core functionality is tested via the test suite. Since fastmcp v3 maintains API compatibility for the methods this project uses (as confirmed in the investigation), and all tests pass, the risk is minimal. If you want extra confidence, run one example with MCP features before merge, but this is not blocking given the evidence.
Key insight: Security fixes for transitive dependencies with proven API compatibility should not be overthought. Ship it.
all-hands-bot
left a comment
There was a problem hiding this comment.
🟢 Good taste - Pragmatic security fix
Linus-Style Analysis:
This is textbook "good taste" engineering:
- Real problem: CVE-2025-69872 (unsafe pickle deserialization) is an actual security vulnerability, not a theoretical concern
- Simplest solution: One-line dependency upgrade. No code changes needed because the upstream library fixed it properly
- No breakage: API compatibility confirmed in previous investigation (thread resolved), 2429 tests green
- Clean dependencies: Lock file shows diskcache cleanly removed, replaced with safer backend (py-key-value-aio[filetree])
Data Structure Check: ✅ No data structure changes
Complexity Check: ✅ No code complexity added
Breaking Change Risk: ✅ Verified compatible via migration guide review
Testing: ✅ Full test suite passing
VERDICT: ✅ Technically sound and ready
However - Repository Policy Note:
Per this repo's guidelines, I'm leaving this as COMMENT rather than APPROVE because:
- fastmcp handles MCP server functionality which could affect agent behavior
- Even with API compatibility confirmed, dependency upgrades in agent tooling warrant lightweight eval testing
- This follows the "flag for eval on behavior-affecting changes" policy
Recommendation: Run a quick smoke test with MCP tools enabled (if applicable to your eval suite), then merge. This is a good fix that should land quickly.
Key Insight: Sometimes the best code review is recognizing when upstream did the work right - fastmcp v3 eliminated the problem at the source.
|
Hi! I started running the integration tests on your PR. You will receive a comment with the results shortly. |
🔄 Running Examples with
|
| Example | Status | Duration | Cost |
|---|---|---|---|
| 01_standalone_sdk/02_custom_tools.py | ✅ PASS | 23.5s | $0.02 |
| 01_standalone_sdk/03_activate_skill.py | ✅ PASS | 20.1s | $0.02 |
| 01_standalone_sdk/05_use_llm_registry.py | ✅ PASS | 12.3s | $0.01 |
| 01_standalone_sdk/07_mcp_integration.py | ✅ PASS | 44.5s | $0.04 |
| 01_standalone_sdk/09_pause_example.py | ✅ PASS | 15.6s | $0.01 |
| 01_standalone_sdk/10_persistence.py | ✅ PASS | 27.0s | $0.02 |
| 01_standalone_sdk/11_async.py | ✅ PASS | 32.6s | $0.03 |
| 01_standalone_sdk/12_custom_secrets.py | ✅ PASS | 10.0s | $0.01 |
| 01_standalone_sdk/13_get_llm_metrics.py | ✅ PASS | 26.0s | $0.02 |
| 01_standalone_sdk/14_context_condenser.py | ✅ PASS | 2m 51s | $0.20 |
| 01_standalone_sdk/17_image_input.py | ✅ PASS | 14.7s | $0.01 |
| 01_standalone_sdk/18_send_message_while_processing.py | ✅ PASS | 15.6s | $0.01 |
| 01_standalone_sdk/19_llm_routing.py | ✅ PASS | 24.2s | $0.02 |
| 01_standalone_sdk/20_stuck_detector.py | ✅ PASS | 15.5s | $0.02 |
| 01_standalone_sdk/21_generate_extraneous_conversation_costs.py | ✅ PASS | 11.3s | $0.00 |
| 01_standalone_sdk/22_anthropic_thinking.py | ✅ PASS | 14.4s | $0.01 |
| 01_standalone_sdk/23_responses_reasoning.py | ✅ PASS | 54.1s | $0.01 |
| 01_standalone_sdk/24_planning_agent_workflow.py | ✅ PASS | 5m 10s | $0.38 |
| 01_standalone_sdk/25_agent_delegation.py | ❌ FAIL Timed out after 600 seconds |
10m 0s | $0.29 |
| 01_standalone_sdk/26_custom_visualizer.py | ✅ PASS | 20.8s | $0.02 |
| 01_standalone_sdk/28_ask_agent_example.py | ✅ PASS | 30.0s | $0.03 |
| 01_standalone_sdk/29_llm_streaming.py | ✅ PASS | 36.1s | $0.03 |
| 01_standalone_sdk/30_tom_agent.py | ✅ PASS | 21.8s | $0.01 |
| 01_standalone_sdk/31_iterative_refinement.py | ✅ PASS | 4m 40s | $0.33 |
| 01_standalone_sdk/32_configurable_security_policy.py | ✅ PASS | 20.4s | $0.02 |
| 01_standalone_sdk/34_critic_example.py | ✅ PASS | 2m 35s | $0.22 |
| 01_standalone_sdk/36_event_json_to_openai_messages.py | ✅ PASS | 11.7s | $0.01 |
| 01_standalone_sdk/37_llm_profile_store.py | ✅ PASS | 4.4s | $0.00 |
| 01_standalone_sdk/38_browser_session_recording.py | ❌ FAIL Timed out after 600 seconds |
10m 0s | $0.03 |
| 01_standalone_sdk/39_llm_fallback.py | ✅ PASS | 10.7s | $0.01 |
| 01_standalone_sdk/40_acp_agent_example.py | ❌ FAIL Exit code 1 |
9.8s | -- |
| 01_standalone_sdk/41_task_tool_set.py | ❌ FAIL Exit code 1 |
4.5s | -- |
| 01_standalone_sdk/42_file_based_subagents.py | ✅ PASS | 54.1s | $0.06 |
| 02_remote_agent_server/01_convo_with_local_agent_server.py | ✅ PASS | 57.1s | $0.05 |
| 02_remote_agent_server/02_convo_with_docker_sandboxed_server.py | ❌ FAIL Exit code 1 |
5.1s | -- |
| 02_remote_agent_server/03_browser_use_with_docker_sandboxed_server.py | ❌ FAIL Exit code 1 |
5.1s | -- |
| 02_remote_agent_server/04_convo_with_api_sandboxed_server.py | ❌ FAIL Exit code 1 |
5m 12s | -- |
| 02_remote_agent_server/07_convo_with_cloud_workspace.py | ✅ PASS | 23.4s | $0.02 |
| 02_remote_agent_server/08_convo_with_apptainer_sandboxed_server.py | ❌ FAIL Exit code 1 |
5.4s | -- |
| 04_llm_specific_tools/01_gpt5_apply_patch_preset.py | ✅ PASS | 21.9s | $0.04 |
| 04_llm_specific_tools/02_gemini_file_tools.py | ✅ PASS | 52.9s | $0.06 |
| 05_skills_and_plugins/01_loading_agentskills/main.py | ✅ PASS | 16.6s | $0.01 |
| 05_skills_and_plugins/02_loading_plugins/main.py | ✅ PASS | 7.3s | $0.01 |
❌ Some tests failed
Total: 43 | Passed: 35 | Failed: 8 | Total Cost: $2.11
Failed examples:
- examples/01_standalone_sdk/25_agent_delegation.py: Timed out after 600 seconds
- examples/01_standalone_sdk/38_browser_session_recording.py: Timed out after 600 seconds
- examples/01_standalone_sdk/40_acp_agent_example.py: Exit code 1
- examples/01_standalone_sdk/41_task_tool_set.py: Exit code 1
- examples/02_remote_agent_server/02_convo_with_docker_sandboxed_server.py: Exit code 1
- examples/02_remote_agent_server/03_browser_use_with_docker_sandboxed_server.py: Exit code 1
- examples/02_remote_agent_server/04_convo_with_api_sandboxed_server.py: Exit code 1
- examples/02_remote_agent_server/08_convo_with_apptainer_sandboxed_server.py: Exit code 1
🧪 Integration Tests ResultsOverall Success Rate: 96.7% 📁 Detailed Logs & ArtifactsClick the links below to access detailed agent/LLM logs showing the complete reasoning process for each model. On the GitHub Actions page, scroll down to the 'Artifacts' section to download the logs.
📊 Summary
📋 Detailed Resultslitellm_proxy_deepseek_deepseek_reasoner
Skipped Tests:
litellm_proxy_gemini_3_pro_preview
litellm_proxy_anthropic_claude_sonnet_4_6
Failed Tests:
litellm_proxy_moonshot_kimi_k2_thinking
Skipped Tests:
|
|
This LGTM since the MCP example test is passing 🙏 Going to merge this |
…ands#2294) Cherry-picked from upstream 193c677. uv.lock regenerated. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>



This upgrade addresses Dependabot alert #44 by removing the diskcache dependency (vulnerable to unsafe pickle deserialization).
Changes:
All 2429 SDK tests pass with the upgrade.
Resolves: https://github.com/OpenHands/software-agent-sdk/security/dependabot/44
Summary
[fill in a summary of this PR]
Checklist
Agent Server images for this PR
• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server
Variants & Base Images
eclipse-temurin:17-jdknikolaik/python-nodejs:python3.12-nodejs22golang:1.21-bookwormPull (multi-arch manifest)
# Each variant is a multi-arch manifest supporting both amd64 and arm64 docker pull ghcr.io/openhands/agent-server:e554199-pythonRun
All tags pushed for this build
About Multi-Architecture Support
e554199-python) is a multi-arch manifest supporting both amd64 and arm64e554199-python-amd64) are also available if needed