Skip to content

fix(connection): block SSRF on connection create/update tool-fetch - #5516

Merged
pedrofrxncx merged 1 commit into
mainfrom
fix/connection-fetch-tools-ssrf-w3
Aug 1, 2026
Merged

fix(connection): block SSRF on connection create/update tool-fetch#5516
pedrofrxncx merged 1 commit into
mainfrom
fix/connection-fetch-tools-ssrf-w3

Conversation

@pedrofrxncx

@pedrofrxncx pedrofrxncx commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Follows the SSRF-hardening lineage on REGISTRY_DISCOVER_TOOLS (#4999, #5488, and others in the registry SSRF vein) — this closes the same gap on a sibling entry point.

The gap: apps/api/src/tools/connection/fetch-tools.ts (fetchToolsFromHttpMCP / fetchToolsFromSSEMCP) is called from CONNECTION_CREATE and CONNECTION_UPDATE with a user-supplied connection_url, and connects to it with the default fetch (redirect-following, no private-IP check). This is the exact same trust boundary discover-tools.ts's isPrivateUrl/resolvesToPrivateAddress/createNoRedirectFetch guard was built for, but an org member could bypass that guard entirely just by calling CONNECTION_CREATE/CONNECTION_UPDATE directly (skipping REGISTRY_DISCOVER_TOOLS) with an HTTP/SSE connection_url pointing at a private/loopback/cloud-metadata address, or a public URL that 3xx-redirects to one.

The fix: extracted the inline private-URL check in discover-tools.ts's handler into a reusable exported guardAgainstPrivateUrl(url) (no behavior change there — same logic, same order of checks, existing tests still cover it), then call that guard plus createNoRedirectFetch() from both fetchToolsFromHttpMCP and fetchToolsFromSSEMCP before connecting. STDIO fetch is untouched (already gated by localMode, no network URL involved).

Regression test: added apps/api/src/tools/connection/fetch-tools.test.ts — asserts fetchToolsFromMCP returns null (its existing failure contract) for an HTTP connection targeting 169.254.169.254 and an SSE connection targeting 127.0.0.1, without ever attempting a network connection (blocked synchronously by the literal-IP check).

Reviewer command: bun test apps/api/src/tools/connection/fetch-tools.test.ts apps/api/src/tools/registry/discover-tools.test.ts

Locally verified: bun run fmt, cd apps/api && bunx tsc --noEmit (clean), the two test files above (22 pass), and bunx oxlint on all three changed files (0 warnings/errors). Full CI validates the rest.


Summary by cubic

Blocks SSRF in connection create/update by enforcing the same private-network URL guard and no-redirect fetch used in REGISTRY_DISCOVER_TOOLS. HTTP/SSE connection_url can no longer target private/loopback/metadata IPs or redirect to them.

  • Bug Fixes
    • Extracted guardAgainstPrivateUrl() from discovery and reused it in fetch-tools for CONNECTION_CREATE and CONNECTION_UPDATE.
    • Applied createNoRedirectFetch() to HTTP and SSE transports to prevent redirect-based bypass.
    • Added tests to ensure fetchToolsFromMCP returns null for private targets (e.g. 169.254.169.254, 127.0.0.1) without making network requests.
    • STDIO path unchanged and remains gated by local mode.

Written for commit 7b73335. Summary will update on new commits.

Review in cubic

Reuse the private-network guard and redirect-blocking that
REGISTRY_DISCOVER_TOOLS already enforces for the same trust boundary
(a user-supplied MCP server URL) in CONNECTION_CREATE/CONNECTION_UPDATE's
tool-fetch path, which had neither: an org member could set an HTTP/SSE
connection_url pointing at a private/metadata address (or a public URL
that 3xx-redirects to one) and the server would connect to it directly,
bypassing the guard entirely by not going through discovery first.
@pedrofrxncx
pedrofrxncx merged commit 1fe8622 into main Aug 1, 2026
26 checks passed
@pedrofrxncx
pedrofrxncx deleted the fix/connection-fetch-tools-ssrf-w3 branch August 1, 2026 01:59
decocms Bot pushed a commit that referenced this pull request Aug 1, 2026
PR: #5516 fix(connection): block SSRF on connection create/update tool-fetch
Bump type: patch

- decocms (apps/api/package.json): 4.158.0 -> 4.158.1
- @decocms/native (apps/native/package.json): 4.158.0 -> 4.158.1

Deploy-Scope: server
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