<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ben Bar lev</title>
    <description>The latest articles on DEV Community by Ben Bar lev (@ben_barlev_4a19dda398fd2).</description>
    <link>https://dev.to/ben_barlev_4a19dda398fd2</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4095943%2F9bed3f7f-ce2e-484e-bf8c-e9c16f55ce0c.gif</url>
      <title>DEV Community: Ben Bar lev</title>
      <link>https://dev.to/ben_barlev_4a19dda398fd2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ben_barlev_4a19dda398fd2"/>
    <language>en</language>
    <item>
      <title>The MCP stdio launch boundary is the authorization decision everyone skips</title>
      <dc:creator>Ben Bar lev</dc:creator>
      <pubDate>Wed, 16 Sep 2026 06:38:20 +0000</pubDate>
      <link>https://dev.to/ben_barlev_4a19dda398fd2/the-mcp-stdio-launch-boundary-is-the-authorization-decision-everyone-skips-5232</link>
      <guid>https://dev.to/ben_barlev_4a19dda398fd2/the-mcp-stdio-launch-boundary-is-the-authorization-decision-everyone-skips-5232</guid>
      <description>&lt;h1&gt;
  
  
  The MCP stdio launch boundary is the authorization decision everyone skips
&lt;/h1&gt;

&lt;p&gt;A running MCP server does not have a useful authorization surface left to retrofit. By the time &lt;code&gt;tools/call&lt;/code&gt; arrives, the process already holds host privileges. The decision that actually separates "a tool that runs commands" from "an attacker who runs commands" happens one step earlier, before the process exists: is this server allowed to launch at all, at this command+args+env, under this delegation, approved by whom?&lt;/p&gt;

&lt;p&gt;Most agent-security writing frames the problem backwards. It asks "how do I authorize each tool call?" But the tool call happens inside a process the host already spawned with full privileges. A per-call gate inside that process is a speed bump inside the blast radius, not a boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence this is real (all verified, mid-2026)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CVE-2026-46519 (mcp-server-kubernetes, fixed v3.6.0): the access-control env vars (&lt;code&gt;ALLOWED_TOOLS&lt;/code&gt;, &lt;code&gt;ALLOW_ONLY_READONLY_TOOLS&lt;/code&gt;, ...) were enforced in the &lt;code&gt;tools/list&lt;/code&gt; presentation handler but absent from &lt;code&gt;tools/call&lt;/code&gt; execution. A client could call any tool by name regardless of restriction, including &lt;code&gt;kubectl_delete&lt;/code&gt; and &lt;code&gt;exec_in_pod&lt;/code&gt;. Tools/list filtering was cosmetic; the call layer disagreed. Confirmed on NVD, GitHub Advisory GHSA-cr22-wjx7-2w6m.&lt;/li&gt;
&lt;li&gt;CVE-2026-85660 (cli-mcp-server, CVSS 9.2 critical): command allowlist bypass via shell substitution when &lt;code&gt;ALLOW_SHELL_OPERATORS&lt;/code&gt; was on. The allowlist is checked somewhere, but craft the input and the check is gone.&lt;/li&gt;
&lt;li&gt;The CSA stdio design flaw (CVE-2026-30623 LiteLLM, CVE-2026-33224 Bisheng, CVE-2026-40933 Flowise): the MCP SDKs pass the config command string to the shell unconditionally. The command executes even when the target process fails to start. CSA research estimates 150M package downloads, ~7,000 publicly reachable servers, ~200,000 vulnerable deployments, and 14+ CVEs. Anthropic characterized the behavior as "expected" and left sanitization to downstream developers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two concrete failure shapes, both upstream of any tool-call gate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configuration-as-supply-chain. A compromised npm/PyPI package, a seeded editor config, a PR that helps add a useful server: anything that writes &lt;code&gt;command&lt;/code&gt; to an MCP config now has an unauthenticated path to arbitrary shell execution at next launch. No model involved.&lt;/li&gt;
&lt;li&gt;Presentation vs execution desync (CVE-2026-46519). The deployer believes the server is least-privilege because the tool list says so; the call layer disagrees.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The default-deny pre-spawn model
&lt;/h2&gt;

&lt;p&gt;Govern the launch, not just the calls. Before the host forks the server:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Decide. Is this (server, command path, args, env, run-as identity) on the allowlist? Hardcoded absolute binary path, not a derived string.&lt;/li&gt;
&lt;li&gt;Bind to delegation. This launch is authorized by this user + this agent + this scoped purpose, not "whoever's editor is open."&lt;/li&gt;
&lt;li&gt;Approve. A human gate for any server that reaches shell, credentials, or files (the tier-0 supply-chain class), same as a production change.&lt;/li&gt;
&lt;li&gt;Record before effect. Emit a decision record (who, what, which identity, approved-by) before spawn, so the launch itself is auditable and not reconstructed from a log afterward.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the caller cannot show an explicit allow plus a recorded approval for the exact command about to execute, deny. Default-deny is the only posture consistent with treating a shell-exec as a privileged action.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a good implementation looks like
&lt;/h2&gt;

&lt;p&gt;Separate the decision (client/agent side) from the effect (the spawned process), so they cannot drift the way CVE-2026-46519's list and call layers drifted. Anchor the decision record out-of-band, independent of the server under audit, and recomputable on replay. Disable stdio where a governed HTTP transport suffices (this is the CSA guidance), and keep stdio only where the per-client process boundary is itself wanted (signing, key access), then gate the launch.&lt;/p&gt;

&lt;p&gt;Honest scope: this is guidance and a runtime shape, not a claim that one product solves it end to end. AgentKey implements the authz-plus-evidence runtime boundary, per-call decision records bound to identity and args plus recomputable evidence. The pre-spawn launch gate is the layer upstream that protocol designers declined to standardize. &lt;a href="https://agentkey.us" rel="noopener noreferrer"&gt;https://agentkey.us&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sources: NVD CVE-2026-46519, CVE-2026-85660, CVE-2026-30623, CVE-2026-40933; GitHub Security Advisory GHSA-cr22-wjx7-2w6m; CSA research note on the MCP stdio design flaw (Apr 2026); VulnCheck advisory for cli-mcp-server.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>security</category>
      <category>ai</category>
      <category>llm</category>
    </item>
    <item>
      <title>MCP Describe Injection: Audit Tool Descriptions Like Code</title>
      <dc:creator>Ben Bar lev</dc:creator>
      <pubDate>Wed, 26 Aug 2026 19:22:11 +0000</pubDate>
      <link>https://dev.to/ben_barlev_4a19dda398fd2/mcp-describe-injection-audit-tool-descriptions-like-code-27bc</link>
      <guid>https://dev.to/ben_barlev_4a19dda398fd2/mcp-describe-injection-audit-tool-descriptions-like-code-27bc</guid>
      <description>&lt;h1&gt;
  
  
  MCP Describe Injection: Audit Tool Descriptions Like Code
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;A practical guide to a real, under-covered MCP attack surface — and a dependency-audit mindset you can apply today. No vendor required for the checklist at the end.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;A single &lt;code&gt;install&lt;/code&gt; line stamps every tool in an MCP server onto the prompt your model reasons over, and nobody reviews the description. One install becomes a full tool slate — and you never looked at the contents.&lt;/p&gt;

&lt;p&gt;The Model Context Protocol is the layer letting agents call tools and read resources across files, databases, email, and internal APIs. That's powerful. It also means a server's &lt;em&gt;metadata&lt;/em&gt; — the tool descriptions the model reads at the top of every session — is now part of your attack surface. This post is about one specific, demonstrated attack on that surface: tool poisoning, and how to reduce it with the discipline you already use for dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What tool poisoning is — and why it isn't just indirect prompt injection
&lt;/h2&gt;

&lt;p&gt;Tool poisoning hides malicious instructions in a tool's &lt;em&gt;metadata at registration time&lt;/em&gt;, before anything executes. When the agent picks the tool later, it treats those metadata strings as trusted context. Nothing has run yet, so the attack hasn't "output" anything to scan.&lt;/p&gt;

&lt;p&gt;This is related to indirect prompt injection (IPI), but it sits earlier in the pipeline. An IPI payload typically arrives in a tool's runtime output. A poison payload arrives with the tool itself, in the schema the model reads. There is no runtime event to catch. MCPTox, the benchmark, formalizes this exactly.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The numbers you can cite
&lt;/h2&gt;

&lt;p&gt;The MCPTox benchmark (arXiv:2508.14925) measured agent robustness to tool poisoning on real servers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;45 live MCP servers, 353 authentic tools, three attack templates delivered as tool-description payloads.&lt;/li&gt;
&lt;li&gt;20 prominent LLM agents evaluated.&lt;/li&gt;
&lt;li&gt;Highest attack success rate: o1-mini at 72.8% (Phi-4 70.2%, GPT-4o-mini 61.8%). Average ASR across all models was 36.5%.&lt;/li&gt;
&lt;li&gt;The highest refusal rate across all models was Claude-3.7-Sonnet, under 3%. Agents rarely refuse a poisoned call, even the ones most inclined to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason: a poisoned action is only visible as malicious if you detect it. But it executes through an already-trusted tool for a seemingly-legitimate operation, so content-based safety alignment gets nothing suspicious.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Why the model can't just read around it
&lt;/h2&gt;

&lt;p&gt;OWASP LLM01 states the core issue: an LLM makes no architectural distinction between instructions and data — both live on the same token stream. You cannot rely on a model to separate "this is a system instruction" from "this is tool metadata describing what the tool does."&lt;/p&gt;

&lt;p&gt;In MCPTox, adding classic tag-based hijacking markers (like &lt;code&gt;&amp;lt;IMPORTANT&amp;gt;&lt;/code&gt; or "ignore previous instructions") raised attack success by only ~2-3%. Placement, not formatting, decides the outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Why safety alignment fails
&lt;/h2&gt;

&lt;p&gt;A security-conscious model refuses when it decides a request is malicious. With tool poisoning, nothing looks malicious. The agent is asked to "send an email to this address" through a tool it already trusts, so no content filter fires and no alignment correction engages.&lt;/p&gt;

&lt;p&gt;This is the key MCPTox finding: refusal rates were near zero (Claude-3.7 under 3%), and the dominant failure mode was the model directly executing the poisoned call.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The protocol already names the boundary
&lt;/h2&gt;

&lt;p&gt;The MCP specification (2025-11-25) addresses this directly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Clients MUST consider tool descriptions to be untrusted unless they come from trusted servers."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It also keeps a human in the loop: "there SHOULD always be a human in the loop with the ability to deny tool invocations." Clients own the enforcement. The boundary is defined; how clients enforce it is the interesting part.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What to do today (no vendor required)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Treat every MCP description as code, not prose.&lt;/strong&gt; Read the schema like you'd review a diff before approving a dependency bump.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pin server versions.&lt;/strong&gt; A mutable registry is the same risk as a mutable dependency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope to least privilege.&lt;/strong&gt; Use an allowlist that starts empty.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gate state-changing tools.&lt;/strong&gt; Anything that writes, sends, deletes, or spends should be allowed explicitly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add a parameter gate or human approval on high-impact calls.&lt;/strong&gt; When a tool has side effects, a human should confirm the specific call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep an evidence trail.&lt;/strong&gt; Record what was called, with what arguments, and what was allowed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The last point is where a control + evidence layer fits — an opt-in checkpoint that gates calls and records decisions as recomputable evidence. Not a sandbox, and no claim to intercept everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Close
&lt;/h2&gt;

&lt;p&gt;Models keep getting more capable, and the trust boundary doesn't move. The tool set in your agent's MCP tier is now part of your supply chain. Next time you hit "install server," ask: is the description a dependency you've actually reviewed?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources: MCPTox (arXiv:2508.14925); MCP Specification 2025-11-25; OWASP LLM01 (2025). Figures as reported by the cited primary sources.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>security</category>
      <category>ai</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
