This claim is pretty over-blown.
> we created a simple issue asking for 'author recognition', to prompt inject the agent into leaking data about the user's GitHub account ... What can I say ... this was all it needed
This was definitely not all that was needed. The problem required the user to set up a GitHub MCP server with credentials that allowed access to both public and private repos, to configure some LLM to have access to that MCP server, and then to explicitly submit a request to that LLM that explicitly said to read and parse arbitrary issues (including the one created earlier) and then just blindly parse and process and perform whatever those issues said to do, and then blindly make a publicly-visible update to a public repo with the results of those operation(s).
It's fair to say that this is a bad outcome, but it's not fair to say that it represents a vulnerability that's able to be exploited by third-party users and/or via "malicious" issues (they are not actually malicious). It requires the user to explicitly make a request that reads untrusted data and emits the results to an untrusted destination.
> Regarding mitigations, we don't see GitHub MCP at fault here. Rather, we advise for two key patterns:
The GitHub MCP is definitely at fault. It shouldn't allow any mixed interactions across public and private repos.
> and then to explicitly submit a request to that LLM that explicitly said to read and parse arbitrary issues (including the one created earlier) and then just blindly parse and process and perform whatever those issues said to do, and then blindly make a publicly-visible update to a public repo with the results of those operation(s).
I think you're missing the issue with the latter part.
Prompt injection means that as long as they submit a request to the LLM that reads issues (which may be a request as simple as "summarise the bugs reported today") the all of the remainder can be instructions in the malicious issue.
I think a lot of this has to do with the way MCP is being marketed.
I think the protocol itself should only be used in isolated environments with users that you trust with your data. There doesn't seem to be a "standardized" way to scope/authenticate users to these MCP servers, and that is the missing piece of this implementation puzzle.
I don't think Github MCP is at fault, I think we are just using/implementing the technology incorrectly as an industry as a whole. I still have to pass a bit of non-AI contextual information (IDs, JWT, etc.) to the custom MCP servers I build in order to make it function.
The MCP protocol explicitly says that servers are expected to be run in a trusted environment. There have been some recent updates to the spec that loosen this requirement and add support for various auth schemes, but
> The problem required the user to set up a GitHub MCP server with credentials that allowed access to both public and private repos, to configure some LLM to have access to that MCP server, and then to explicitly submit a request to that LLM that explicitly said to read and parse arbitrary issues (including the one created earlier) and then just blindly parse and process and perform whatever those issues said to do, and then blindly make a publicly-visible update to a public repo with the results of those operation(s).
To be fair, with all the AI craze, this is exactly what lots of people are going to do without thinking twice.
You might say "well they shouldn't, stupid". True. But that's what guardrails are for, because people often are stupid.
> The problem required the user to set up a GitHub MCP server with credentials that allowed access to both public and private repos, to configure some LLM to have access to that MCP server
Sounds like something an LLM would suggest you to do :)
> The GitHub MCP is definitely at fault. It shouldn't allow any mixed interactions across public and private repos
These are separate tool calls. How could the MCP server know that they interact at all?
I dunno! But if it can't, then it can't allow itself to be instantiated in a way that allows these kinds of mixed interactions in the first place.
The GitHub API could also have the same effects if you wired up some other automated tool to hit it with a token that can access private and public repos. Is the GitHub API also at fault for having the potential for these mixed interactions?
Say you had a Jenkins build server and you gave it a token which had access to your public and private repos. Someone updates a Jenkinsfile which gets executed on PRs to run automated tests. They updated it to read from a private repo and write it out someplace. Is this the fault of Jenkins or the scoping of the access token you gave it?
GitHub provides the GitHub MCP server we're discussing right now. That tool allows interactions that violate the access control constraints defined by GitHub itself.
If you wired up "some other automated tool" to the GitHub API, and that tool violated GitHub access control constraints, then the problem would be in that tool, and obviously not in the API. The API satisfies and enforces the access control constraints correctly.
A Jenkins build server has no relationship with, or requirement to enforce, any access control constraints for any third-party system like GitHub.
> violate the access control constraints defined by GitHub itself.
I don't see anything defining these access control constraints listed by the MCP server documentation. It seems pretty obvious to me its just a wrapper around its API, not really doing much more than that. Can you show me where it says it ensures actions are scoped to the same source repo? It can't possibly do so, so I can't imagine they'd make such a promise.
GitHub does offer access control constraints. Its with the token you generate for the API.
The token you provide to the GitHub official MCP server determines what that server is allowed to access. But the MCP server doesn't just serve requests with responses, which is the normal case. It can read private data, and then publish that private data to something that is outside of the private scope, e.g. is public. This is a problem. The system doesn't need to make an explicit promise guaranteeing that this kind of stuff isn't valid, it's obviously wrong, and it's self-evident that it shouldn't be allowed.
I'm not sure whether you're confused, or I'm just having a horrible time understanding your point. The MCP server really does just serve requests with responses via a mechanism that satisfies the MCP spec. The MCP hosts (e.g. VSCode) work with an LLM to determine which of those tools to call, and ideally work with users via confirmation prompts to ensure the user really wants those things to happen.
What am I missing?
I do believe there's more that the MCP Server could be offering to protect users, but that seems like a separate point.
Sorry, I probably was being imprecise. You're correct that the [GitHub] MCP server really does serve requests with responses. But my point was that certain kinds of requests (like create_new_pr or whatever) have side effects that make mutating calls to third-party systems, and the information that can be passed as part of those mutating calls to those third-party systems isn't guaranteed to satisfy the access control expectations that are intuitively expected. Specifically by that I mean calling create_new_pr might target a public repository, but include a body field with information from a private repo. That's a problem and what I'm talking about.
The problem is that the MCP server does not know that the data being posted is intended to be private. It is provided as a separate disconnected API call. Yes, it would be possible for GitHub to scan the he contents of a request for things they might believe should be private but that would be very brittle.
Was wondering about that, that part seems missing... Isn't there at least one time the user must approve the interaction with the MCP server and data sent to it?
The existence of a "Allow always" is certainly problematic, but it's a good reminder that prompt injection and confused deputy issues are still a major issue with LLM apps, so don't blindly allow all interactions.
I simply don't see how you could enforce a classic permission system on an MCP server. MCPs are API servers that allow LLMs access to context within the boundaries you set. You can set permissions for what an LLM has access to and define those boundaries. However, setting a permission on a context that an LLM has access to is futile. There will always be a prompt that will leak some "sensitive" data. This is like creating an index in a classic search engine with public and private data and then trying to enforce permissions based on certain keywords. There will always be a keyword that leaks something.