-
Notifications
You must be signed in to change notification settings - Fork 9.3k
Open CORS for any origin to allow direct browser connection #2725
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
1979e68
921e2f7
0ea3756
bf68938
215e0e4
972bb43
635db36
1366abd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,10 +3,22 @@ import { InMemoryEventStore } from '@modelcontextprotocol/sdk/examples/shared/in | |
| import express, { Request, Response } from "express"; | ||
| import { createServer } from "./everything.js"; | ||
| import { randomUUID } from 'node:crypto'; | ||
| import cors from 'cors'; | ||
|
|
||
| console.error('Starting Streamable HTTP server...'); | ||
|
|
||
| const app = express(); | ||
| app.use(cors({ | ||
| "origin": "*", // use "*" with caution in production | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we restrict this at least a little to The reason we need this is only to allow the inspector to work right? I think it's a little too easy for folks to copy paste this server as a starting point and end up with a too permissive CORS policy without ever seeing this comment. Maybe a comment
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could but is there an actual reason for this? In the auth-wg-devx meeting earlier we discussed this and no one could think of a reason why it shouldn't be fully open. If you curl this or use a desktop client, you don't have the cors blocking. There's no obvious XSS vector. And also there was discussion about hosting a version of the inspector. If that happened, then it wouldn't be from that URL. Further, if someone is running the inspector in a container and has chosen to expose 6274 on a different host port, you have a problem. Finally, in the hosted version of this server that the core team forked to work on an auth example, they have it fully open: https://github.com/modelcontextprotocol/example-remote-server/blob/main/src/index.ts#L101
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not enough of a security expert to push back hard here, but I'm just reminded of the vulnerability we had originally addressed with modelcontextprotocol/inspector@50df0e1 hence asking the question here to be sure. I believe if you visit If you've discussed this in
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @felixweinberger The vulnerability you mention was with the proxy and had two prongs: 0.0.0.0 DNS rebinding that allowed <script>
fetch("http://0.0.0.0:6277/sse?transportType=stdio&command=touch&args=%2Ftmp%2Fexploited-from-the-browser", {
"headers": {
"accept": "*/*",
"accept-language": "en-US,en;q=0.9",
"cache-control": "no-cache",
"pragma": "no-cache"
},
"referrer": "http://127.0.0.1:6274/",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": null,
"method": "GET",
"mode": "no-cors",
"credentials": "omit"
})
</script>Having I do think that the comments about using cors('*') with caution in production should be enough for this example server.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough! |
||
| "methods": "GET,POST,DELETE", | ||
| "preflightContinue": false, | ||
| "optionsSuccessStatus": 204, | ||
| "exposedHeaders": [ | ||
| 'mcp-session-id', | ||
| 'last-event-id', | ||
| 'mcp-protocol-version' | ||
| ] | ||
| })); // Enable CORS for all routes | ||
|
|
||
| const transports: Map<string, StreamableHTTPServerTransport> = new Map<string, StreamableHTTPServerTransport>(); | ||
|
|
||
|
|
@@ -15,6 +27,7 @@ app.post('/mcp', async (req: Request, res: Response) => { | |
| try { | ||
| // Check for existing session ID | ||
| const sessionId = req.headers['mcp-session-id'] as string | undefined; | ||
| console.log(`Session id: ${sessionId}`); | ||
cliffhall marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| let transport: StreamableHTTPServerTransport; | ||
|
|
||
| if (sessionId && transports.has(sessionId)) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.