Skip to content

Security hardening: MCP server auth#540

Merged
corinagum merged 8 commits into
mainfrom
cg/mcp-auth-hardening
May 7, 2026
Merged

Security hardening: MCP server auth#540
corinagum merged 8 commits into
mainfrom
cg/mcp-auth-hardening

Conversation

@corinagum
Copy link
Copy Markdown
Collaborator

@corinagum corinagum commented Apr 23, 2026

Summary

Addresses security scan finding #14 (MCP server mounted without auth). TypeScript half of a 2-SDK PR set (.NET PR is on the same branch name).

Note: Earlier revisions of this branch also addressed finding #15 (MCP client URL validation). #15 has been dropped — the SSRF risk against MCP client URLs is low-likelihood and the default private-network filter created friction for legitimate on-prem MCP customers. Reverted in commit fd3444f8.

#14 — MCP server auth

New opt-in requireAuth hook on McpPluginOptions:

new McpPlugin({
  requireAuth: (req) => req.headers.authorization === 'Bearer ...'
})

Hook is called once per inbound MCP request via an Express-level prefix middleware on /mcp (covers any current or future handler registered under that path). false/throw returns 401. When unset, all requests are accepted and a one-time startup warning fires when the SSE transport comes up.

Design doc

design/mcp-server-auth-options.md

E2E verified

  • Middleware gating: /mcp returns 401 without auth, SSE handshake on correct bearer
  • Activity path (/api/messages): bot responded to a devtools chat message with REQUIRE_AUTH=1 active simultaneously
  • Startup warning fires when requireAuth is unset; silent when set

@corinagum corinagum marked this pull request as ready for review April 29, 2026 19:24
Copilot AI review requested due to automatic review settings April 29, 2026 19:24
@corinagum corinagum force-pushed the cg/mcp-auth-hardening branch from 3332a5f to 9e5624e Compare April 29, 2026 19:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds security hardening for MCP integrations by introducing opt-in MCP server authentication and default URL validation to mitigate client-side SSRF risks.

Changes:

  • Add requireAuth hook to McpPlugin to gate inbound MCP /mcp requests with 401 on failure.
  • Add validateMcpServerUrl URL gate (scheme + DNS/private-network filtering) and expose allowPrivateNetwork / validateUrl params in the MCP client.
  • Add/adjust Jest tests to cover URL validation and server auth behavior.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
external/mcpclient/src/url-validation.ts Implements default URL scheme + private-network/DNS-based validation and error type.
external/mcpclient/src/url-validation.spec.ts Adds unit tests for URL validation behavior and edge cases.
external/mcpclient/src/mcp-client-types.ts Extends client params with allowPrivateNetwork and validateUrl.
external/mcpclient/src/mcp-client-plugin.ts Wires URL validation into MCP client creation flow.
external/mcpclient/src/mcp-client-plugin.spec.ts Stubs DNS lookup to keep existing tests deterministic/offline.
external/mcp/src/plugin.ts Adds requireAuth option, startup warning, and auth middleware for MCP SSE route prefix.
external/mcp/src/plugin.spec.ts Adds unit tests for new checkAuth behavior with various outcomes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread external/mcpclient/src/url-validation.ts Outdated
Comment thread external/mcpclient/src/url-validation.ts Outdated
Comment thread external/mcp/src/plugin.ts Outdated
Comment thread external/mcp/src/plugin.ts Outdated
@corinagum corinagum changed the title Security hardening: MCP server auth + client URL validation Security hardening: MCP server auth May 5, 2026
corinagum added 7 commits May 6, 2026 16:22
Per team decision, the MCP client SSRF guard adds friction for legitimate
on-prem MCP customers and the underlying risk is low-likelihood. Reverting
the client-side URL validation work; the McpPlugin server auth (#14) and the
Express-level path-prefix middleware refactor are kept.

Removes:
- external/mcpclient/src/url-validation.ts (and spec)
- McpClientPluginParams.allowPrivateNetwork + validateUrl
- validateMcpServerUrl call in makeMcpClient
- DNS mock added to mcp-client-plugin.spec.ts
@corinagum corinagum force-pushed the cg/mcp-auth-hardening branch from fd3444f to 2d8f3a3 Compare May 6, 2026 23:22
In checkAuth, after the requireAuth try/catch, return early without
writing a 401 if req.aborted is set. The client has already disconnected;
attempting to set headers on a destroyed stream produces noisy warnings
without changing observable behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@corinagum corinagum merged commit 642cdd1 into main May 7, 2026
7 checks passed
@corinagum corinagum deleted the cg/mcp-auth-hardening branch May 7, 2026 17:30
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.

3 participants