Well, that's why REST api's exist. You don't expose your database to your clients. You put a layer like REST to help with authorization.
But everyone needs to have an MCP server now. So Supabase implements one, without that proper authorization layer which knows the business logic, and voila. It's exposed.
Code _is_ the security layer that sits between database and different systems.
While I'm not very fond of the "lethal trifecta" and other terminology that makes it seem problems with LLMs are somehow new, magic, or a case of bad implementation, 'simonw actually makes a clear case why REST APIs won't save you: because that's not where the problem is.
Obviously, if some actions are impossible to make through a REST API, then LLM will not be able to execute them by calling the REST API. Same is true about MCP - it's all just different ways to spell "RPC" :).
(If the MCP - or REST API - allows some actions it shouldn't, then that's just a good ol' garden variety security vulnerability, and LLMs are irrelevant to it.)
The problem that's "unique" to MCP or systems involving LLMs is that, from the POV of MCP/API layer, the user is acting by proxy. Your actual user is the LLM, which serves as a deputy for the traditional user[0]; unfortunately, it also happens to be very naive and thus prone to social engineering attacks (aka. "prompt injections").
It's all fine when that deputy only ever sees the data from the user and from you; but the moment it's exposed to data from a third party in any way, you're in trouble. That exposure could come from the same LLM talking to multiple MCPs, or because the user pasted something without looking, or even from data you returned. And the specific trouble is, the deputy can do things the user doesn't want it to do.
There's nothing you can do about it from the MCP side; the LLM is acting with user's authority, and you can't tell whether or not it's doing what the user wanted.
That's the basic case - other MCP-specific problems are variants of it with extra complexity, like more complex definition of who the "user" is, or conflicting expectations, e.g. multiple parties expecting the LLM to act in their interest.
That is the part that's MCP/LLM-specific and fundamentally unsolvable. Then there's a secondary issue of utility - the whole point of providing MCP for users delegating to LLMs is to allow the computer to invoke actions without involving the users; this necessitates broad permissions, because having to ask the actual human to authorize every single distinct operation would defeat the entire point of the system. That too is unsolvable, because the problems and the features are the same thing.
Problems you can solve with "code as a security layer" or better API design are just old, boring security problems, that are an issue whether or not LLMs are involved.
--
[0] - Technically it's the case with all software; users are always acting by proxy of software they're using. Hell, the original alternative name for a web browser is "user agent". But until now, it was okay to conceptually flatten this and talk about users acting on the system directly; it's only now that we have "user agents" that also think for themselves.
It doesnt' have to be REST, but it does have to prevent the LLM from having access to data you wouldn't want the user having access to. How exactly you accomplish that is up to you, but the obvious way would be to have the LLM use the same APIs you would use to implement a UI for the data (which would typically be REST or some other RPC). The ability to run SQL would allow the LLM to do more interesting things for which an API has not been written, but generically adding auth to arbitrary sql queries is not a trivial task, and does not seem to have even been attempted here.
> injection attacks are confined to the rows that the user has access to, which is OK
Is it? The malicious instructions would have to silently exfiltrate and collect data individually for each user as they access the system, but the end-result wouldn't be much better.
But everyone needs to have an MCP server now. So Supabase implements one, without that proper authorization layer which knows the business logic, and voila. It's exposed.
Code _is_ the security layer that sits between database and different systems.