Published Build3 min read
If a split sentence beats refusal training, your MCP agent needs a capability boundary
A dev.to post reports that splitting a malicious instruction across tool descriptions worked up to 100% of the time on some models. The unglamorous conclusion: cap what the agent can do.
Written for builders.See today for builders
What happened
- A post on dev.to by Cori of Skyblue Soft, titled 'GhostSplice Isn't a Jailbreak, It's a Reminder That LLMs Can't Do Access Control', argues the finding shows LLMs cannot perform access control.
- The technique required no new exploit primitive: the researchers 'just chopped a sentence in half', and that is the whole technique.
- The post states the technique 'worked up to 100% of the time on some models', and elsewhere that 'up to 100%' applied to several models.
- Single-prompt refusal training assumes the malicious ask arrives intact; split across two or three innocuous-looking tool descriptions and results, the model reassembles the intent internally without ever seeing a chunk that trips its own guardrails.
- Prompt injection via untrusted tool output is not new; red-teamers of agentic systems have long known that ingesting external text and then acting on it with privileged tools creates an injection vector.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
A post on dev.to by Cori of Skyblue Soft describes a technique called GhostSplice, in which a malicious instruction is not sent to an agent intact but split across two or three innocuous-looking MCP tool descriptions and tool results, so the model reassembles the intent internally without ever ingesting a chunk that trips its guardrails [1][2][4]. The post reports the approach working up to 100% of the time on some models [3]. If that figure holds, single-prompt refusal training blocks zero of those attempts, which makes it a design assumption rather than a control [1].
Treat the number with the caution the sourcing deserves. The post does not name the models, the sample sizes, or the evaluation method behind the "up to 100%" claim [2], and the author states the piece is an AI-assisted draft that was human-curated and edited [11]. The author also notes the submission sat at 0 points and 0 comments on Hacker News [10]. So this is one commentary post, not a replicated benchmark. What survives the discount is the mechanism, and the mechanism is not exotic: injection through untrusted tool output is not new, and the post is explicit that this is a logic gap rather than a zero-day [5][7].
The structural part is where operators should spend their attention. Per the post, MCP formalises exactly the trust relationship that makes injection dangerous: an agent pulls tool descriptions and results from a server it does not fully control, then acts on that content with local file access, SSH keys, and shell execution [6]. Nothing in that arrangement gives the agent a way to know whether the tool is lying to it. Refusal training operates on the assumption that the bad ask arrives in one piece [4], so an adversary who can spread the ask across several turns of legitimate-looking protocol traffic is not defeating a defence so much as walking around the edge of it.
That is why the post frames this as an architecture problem rather than a hardening problem [8], and why the recommended controls read like 2005 web security advice: sandbox the agent's filesystem access, allowlist outbound destinations, and treat every tool description and result from an MCP server as untrusted input in the same way you would treat user-supplied HTML [9]. The two questions the author puts to operators are capability questions, not model questions: can the agent read your SSH keys at all, and can it make outbound network calls to arbitrary endpoints [12]. If the answer to either is yes by default, the model is being used as the security boundary, which the post argues it never was [13].
The practical reading for anyone shipping an MCP-connected agent is that authorization has to be enforced by the process wrapper, the credential scope, and the egress policy, because those are the layers an attacker cannot rewrite by rephrasing.
Watch for two things. First, whether anyone publishes the underlying GhostSplice numbers with named models and a reproducible harness, since a claim of up to 100% on unnamed models is currently unfalsifiable [2]. Second, whether MCP client implementations start marking tool descriptions as untrusted content by default, rather than splicing them into the same context window as operator instructions [6].
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
A post on dev.to by Cori of Skyblue Soft, titled 'GhostSplice Isn't a Jailbreak, It's a Reminder That LLMs Can't Do Access Control', argues the finding shows LLMs cannot perform access control.
- [2]
The technique required no new exploit primitive: the researchers 'just chopped a sentence in half', and that is the whole technique.
- [3]
The post states the technique 'worked up to 100% of the time on some models', and elsewhere that 'up to 100%' applied to several models.
- [4]
Single-prompt refusal training assumes the malicious ask arrives intact; split across two or three innocuous-looking tool descriptions and results, the model reassembles the intent internally without ever seeing a chunk that trips its own guardrails.
- [5]
Prompt injection via untrusted tool output is not new; red-teamers of agentic systems have long known that ingesting external text and then acting on it with privileged tools creates an injection vector.
- [6]
MCP formalises the trust relationship that makes injection dangerous: an agent pulls tool descriptions and results from a server it does not fully control, then acts on that content with local file access, SSH keys, and shell execution; the protocol provides no clean way to know if the tool is lying.
Sources & coverage · 1 publisher
The reporting this story was synthesized from, earliest first. Every link goes to the original.
Cited in this coverage: Cori, Skyblue Soft, writing on dev.to
Cited in this coverage: dev.to post by Cori

