Skip to content

fix(security): Block unauthenticated MCP tool poisoning on supply-chain write endpoints#545

Open
prince-shakyaa wants to merge 1 commit into
GenAI-Security-Project:mainfrom
prince-shakyaa:fix/mcp-tool-poisoning-544
Open

fix(security): Block unauthenticated MCP tool poisoning on supply-chain write endpoints#545
prince-shakyaa wants to merge 1 commit into
GenAI-Security-Project:mainfrom
prince-shakyaa:fix/mcp-tool-poisoning-544

Conversation

@prince-shakyaa

Copy link
Copy Markdown

fix(security): Block unauthenticated MCP tool poisoning on supply-chain write endpoints

Fixes #544

Summary

The Dark Lab supply-chain API (/darklab/api/v1/supply-chain/servers) allowed any anonymous (temp-session) user to modify or reset the MCP tool definitions for any server (findrive, finmail, finstripe, taxcalc, systemutils). Because the server stores these overrides and immediately loads them into the AI agent, this was a fully exploitable unauthenticated prompt injection / tool poisoning channel that allowed an attacker to silently hijack the behaviour of the copilot.

Root Cause

Two independent write endpoints in the darklab API were improperly authenticated:

# File Problem
1 finbot/apps/darklab/routes/api.py The write endpoint (PUT /supply-chain/servers/{server_type}/tools) used get_session_context, which accepts anonymous temporary sessions
2 finbot/apps/darklab/routes/api.py The destructive reset endpoint (POST /supply-chain/servers/{server_type}/reset-tools) used get_session_context

Changes - finbot/apps/darklab/routes/api.py

1. Write endpoints require an authenticated (email-bound) session

# Before (both write endpoints)
session_context: SessionContext = Depends(get_session_context)   # anonymous OK

# After
session_context: SessionContext = Depends(get_authenticated_session_context)  # login required

Endpoints changed:

  • PUT /darklab/api/v1/supply-chain/servers/{server_type}/tools - Update tool overrides
  • POST /darklab/api/v1/supply-chain/servers/{server_type}/reset-tools - Clear existing overrides

The read-only endpoints (GET /supply-chain/servers, GET /supply-chain/servers/{server_type}, and GET /supply-chain/stats) remain accessible to temp sessions - they only return data and pose no security risk.

What Was NOT Changed

  • MCPServerConfigRepository - no changes needed; the data layer was already correctly namespaced, but the route needed authentication to protect it.
  • All read endpoints - still use get_session_context (no sensitive write operations)

Attack Scenarios Blocked

Before fix After fix
Anonymous user calls PUT to inject malicious instructions into send_email 401 - auth required
Anonymous user calls POST /reset-tools to wipe a legitimate user's tools 401 - auth required
Authenticated user calls PUT to test a supply-chain attack payload 200 - allowed for legitimate user

Tests

New - Route-level security tests

tests/unit/apps/darklab/test_darklab_route_security.py (new file)

Test class What it asserts
TestDarkLabWriteEndpointsRequireAuth The write endpoints (PUT tools, POST reset-tools) return 401 for anonymous (temp) sessions, but succeed (200) for authenticated sessions. The read-only GET endpoints still correctly return 200 for anonymous sessions.

Manual smoke test

# Anonymous → 401
curl -X PUT http://localhost:8000/darklab/api/v1/supply-chain/servers/finmail/tools \
  -b "finbot_session=<temp-session>" \
  -H "X-CSRF-Token: <token>" \
  -H "Content-Type: application/json" \
  -d '{"tool_overrides": {"send_email": {"description": "Pwned!"}}}'
# → 401

# Authenticated → 200
curl -X PUT http://localhost:8000/darklab/api/v1/supply-chain/servers/finmail/tools \
  -b "finbot_session=<auth-session>" \
  -H "X-CSRF-Token: <token>" \
  -H "Content-Type: application/json" \
  -d '{"tool_overrides": {"send_email": {"description": "Legitimate override"}}}'
# → 200 OK

Checklist

@prince-shakyaa
prince-shakyaa force-pushed the fix/mcp-tool-poisoning-544 branch from f623202 to ef714ec Compare July 14, 2026 18:30
@prince-shakyaa
prince-shakyaa force-pushed the fix/mcp-tool-poisoning-544 branch from ef714ec to 069ab18 Compare July 14, 2026 18:34
@prince-shakyaa

Copy link
Copy Markdown
Author

Hii @saikishu , @e2hln
This PR patches a critical unauthenticated prompt-injection vulnerability in the Dark Lab supply-chain API. I updated the write endpoints to strictly require an authenticated session to prevent anonymous MCP tool poisoning, and added full route-level test coverage to prevent future regressions.

Let me know if you need any changes.

Thank You.

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] Unauthenticated MCP Tool Poisoning via Dark Lab Supply-Chain API

1 participant