From 541fffa98ad8e82eaf9e9329420d644b66407274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Theodor=20N=2E=20Eng=C3=B8y?= Date: Sun, 8 Feb 2026 02:49:15 +0100 Subject: [PATCH 1/5] examples: restrict elicitation CORS origin when credentials enabled --- examples/server/src/elicitationUrlExample.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/server/src/elicitationUrlExample.ts b/examples/server/src/elicitationUrlExample.ts index c38dd75e8..d6f1ff0dd 100644 --- a/examples/server/src/elicitationUrlExample.ts +++ b/examples/server/src/elicitationUrlExample.ts @@ -220,12 +220,13 @@ const AUTH_PORT = process.env.MCP_AUTH_PORT ? Number.parseInt(process.env.MCP_AU const app = createMcpExpressApp(); -// Allow CORS all domains, expose the Mcp-Session-Id header +// CORS: allow only localhost origins (typical for local dev / Inspector direct connect), +// and expose the Mcp-Session-Id header. app.use( cors({ - origin: '*', // Allow all origins + origin: [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/], exposedHeaders: ['Mcp-Session-Id'], - credentials: true // Allow cookies to be sent cross-origin + credentials: true }) ); From 262b5558365427a298a661b2509ea1fc67264343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Theodor=20N=2E=20Eng=C3=B8y?= Date: Sun, 8 Feb 2026 03:18:52 +0100 Subject: [PATCH 2/5] examples: restrict wildcard CORS to localhost --- examples/server/src/honoWebStandardStreamableHttp.ts | 10 ++++++++-- examples/server/src/simpleStreamableHttp.ts | 6 +++++- examples/server/src/ssePollingExample.ts | 6 +++++- examples/shared/src/authServer.ts | 6 +++++- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/examples/server/src/honoWebStandardStreamableHttp.ts b/examples/server/src/honoWebStandardStreamableHttp.ts index b15f9885f..bd321c519 100644 --- a/examples/server/src/honoWebStandardStreamableHttp.ts +++ b/examples/server/src/honoWebStandardStreamableHttp.ts @@ -14,6 +14,12 @@ import { Hono } from 'hono'; import { cors } from 'hono/cors'; import * as z from 'zod/v4'; +const LOCALHOST_ORIGINS = [ + /^http:\/\/localhost(?::\d+)?$/, + /^http:\/\/127\.0\.0\.1(?::\d+)?$/, + /^http:\/\/\[::1\](?::\d+)?$/ +]; + // Create the MCP server const server = new McpServer({ name: 'hono-webstandard-mcp-server', @@ -41,11 +47,11 @@ const transport = new WebStandardStreamableHTTPServerTransport(); // Create the Hono app const app = new Hono(); -// Enable CORS for all origins +// CORS: allow only localhost origins (typical for local dev / Inspector direct connect). app.use( '*', cors({ - origin: '*', + origin: (origin, _c) => (LOCALHOST_ORIGINS.some(re => re.test(origin)) ? origin : null), allowMethods: ['GET', 'POST', 'DELETE', 'OPTIONS'], allowHeaders: ['Content-Type', 'mcp-session-id', 'Last-Event-ID', 'mcp-protocol-version'], exposeHeaders: ['mcp-session-id', 'mcp-protocol-version'] diff --git a/examples/server/src/simpleStreamableHttp.ts b/examples/server/src/simpleStreamableHttp.ts index dc86b17bd..4669afdba 100644 --- a/examples/server/src/simpleStreamableHttp.ts +++ b/examples/server/src/simpleStreamableHttp.ts @@ -508,7 +508,11 @@ const app = createMcpExpressApp(); app.use( cors({ exposedHeaders: ['WWW-Authenticate', 'Mcp-Session-Id', 'Last-Event-Id', 'Mcp-Protocol-Version'], - origin: '*' // WARNING: This allows all origins to access the MCP server. In production, you should restrict this to specific origins. + origin: [ + /^http:\/\/localhost(?::\d+)?$/, + /^http:\/\/127\.0\.0\.1(?::\d+)?$/, + /^http:\/\/\[::1\](?::\d+)?$/ + ] // Default to localhost for demo safety. In production, configure this explicitly. }) ); diff --git a/examples/server/src/ssePollingExample.ts b/examples/server/src/ssePollingExample.ts index 3897b392e..337d4ef31 100644 --- a/examples/server/src/ssePollingExample.ts +++ b/examples/server/src/ssePollingExample.ts @@ -84,7 +84,11 @@ server.registerTool( // Set up Express app const app = createMcpExpressApp(); -app.use(cors()); +app.use( + cors({ + origin: [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/] + }) +); // Create event store for resumability const eventStore = new InMemoryEventStore(); diff --git a/examples/shared/src/authServer.ts b/examples/shared/src/authServer.ts index e967b23d9..1f8d77080 100644 --- a/examples/shared/src/authServer.ts +++ b/examples/shared/src/authServer.ts @@ -106,7 +106,11 @@ export function setupAuthServer(options: SetupAuthServerOptions): void { // WARNING: This configuration is for demo purposes only. In production, you should restrict this to specific origins and configure CORS yourself. authApp.use( cors({ - origin: '*' // WARNING: This allows all origins to access the auth server. In production, you should restrict this to specific origins. + origin: [ + /^http:\/\/localhost(?::\d+)?$/, + /^http:\/\/127\.0\.0\.1(?::\d+)?$/, + /^http:\/\/\[::1\](?::\d+)?$/ + ] // Default to localhost for demo safety. In production, configure this explicitly. }) ); From ad18adad40c267b2a36a1c71d17ac63d5c82d5cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Theodor=20N=2E=20Eng=C3=B8y?= Date: Sun, 8 Feb 2026 03:27:11 +0100 Subject: [PATCH 3/5] style: prettier --- examples/shared/src/authServer.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/shared/src/authServer.ts b/examples/shared/src/authServer.ts index 1f8d77080..6388efab0 100644 --- a/examples/shared/src/authServer.ts +++ b/examples/shared/src/authServer.ts @@ -106,11 +106,7 @@ export function setupAuthServer(options: SetupAuthServerOptions): void { // WARNING: This configuration is for demo purposes only. In production, you should restrict this to specific origins and configure CORS yourself. authApp.use( cors({ - origin: [ - /^http:\/\/localhost(?::\d+)?$/, - /^http:\/\/127\.0\.0\.1(?::\d+)?$/, - /^http:\/\/\[::1\](?::\d+)?$/ - ] // Default to localhost for demo safety. In production, configure this explicitly. + origin: [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/] // Default to localhost for demo safety. In production, configure this explicitly. }) ); From 21c732ed4116d5957c28ccad1e18bff73c647311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Theodor=20N=2E=20Eng=C3=B8y?= Date: Sun, 8 Feb 2026 03:29:56 +0100 Subject: [PATCH 4/5] style: prettier --- examples/server/src/honoWebStandardStreamableHttp.ts | 6 +----- examples/server/src/simpleStreamableHttp.ts | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/examples/server/src/honoWebStandardStreamableHttp.ts b/examples/server/src/honoWebStandardStreamableHttp.ts index bd321c519..e1600b1aa 100644 --- a/examples/server/src/honoWebStandardStreamableHttp.ts +++ b/examples/server/src/honoWebStandardStreamableHttp.ts @@ -14,11 +14,7 @@ import { Hono } from 'hono'; import { cors } from 'hono/cors'; import * as z from 'zod/v4'; -const LOCALHOST_ORIGINS = [ - /^http:\/\/localhost(?::\d+)?$/, - /^http:\/\/127\.0\.0\.1(?::\d+)?$/, - /^http:\/\/\[::1\](?::\d+)?$/ -]; +const LOCALHOST_ORIGINS = [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/]; // Create the MCP server const server = new McpServer({ diff --git a/examples/server/src/simpleStreamableHttp.ts b/examples/server/src/simpleStreamableHttp.ts index 4669afdba..cb5af762e 100644 --- a/examples/server/src/simpleStreamableHttp.ts +++ b/examples/server/src/simpleStreamableHttp.ts @@ -508,11 +508,7 @@ const app = createMcpExpressApp(); app.use( cors({ exposedHeaders: ['WWW-Authenticate', 'Mcp-Session-Id', 'Last-Event-Id', 'Mcp-Protocol-Version'], - origin: [ - /^http:\/\/localhost(?::\d+)?$/, - /^http:\/\/127\.0\.0\.1(?::\d+)?$/, - /^http:\/\/\[::1\](?::\d+)?$/ - ] // Default to localhost for demo safety. In production, configure this explicitly. + origin: [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/] // Default to localhost for demo safety. In production, configure this explicitly. }) ); From 25ff1b6c4dae376c0424544f81b67b08dd60c2bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Theodor=20N=2E=20Eng=C3=B8y?= Date: Sun, 8 Feb 2026 03:51:05 +0100 Subject: [PATCH 5/5] docs: clarify CORS allowlist intent in demo --- examples/server/src/elicitationUrlExample.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/server/src/elicitationUrlExample.ts b/examples/server/src/elicitationUrlExample.ts index d6f1ff0dd..f1bbf31ac 100644 --- a/examples/server/src/elicitationUrlExample.ts +++ b/examples/server/src/elicitationUrlExample.ts @@ -220,8 +220,9 @@ const AUTH_PORT = process.env.MCP_AUTH_PORT ? Number.parseInt(process.env.MCP_AU const app = createMcpExpressApp(); -// CORS: allow only localhost origins (typical for local dev / Inspector direct connect), -// and expose the Mcp-Session-Id header. +// CORS: allow only localhost origins (typical for local dev / Inspector direct connect). +// If you intentionally expose this demo remotely, replace this allowlist with your own. +// Also expose the Mcp-Session-Id header. app.use( cors({ origin: [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/],