DEV Community

Neeraj Kumar Singh Beshane
Neeraj Kumar Singh Beshane

Posted on

The Goalkeeper Rule Your Agent Gateway Forgot

New here? Securing the Agentic Stack is a weekly operator read on AI and security, mapped to one stable six-layer model. Start with the six-layer spine.

On July 19, Spain lifted the World Cup in New Jersey, and across those 104 matches a goalkeeper somewhere picked up a ball they were not allowed to touch.

Every fan watching knew it was an offence. Very few could explain the actual rule, and that gap is exactly where this week's worst disclosure lives.

Here is the moment. A defender, under no pressure at all, taps the ball back to their own keeper, who scoops it up inside the six-yard box. Indirect free kick. Now change one thing. Same keeper, same box, same ball, same hands, but this time it came off a teammate's head instead of their boot. Perfectly legal.

Nothing about the keeper changed. Nothing about the location changed. What changed is who gave them the ball, and how. Law 12 does not ask where the keeper is standing. It asks where the ball came from.

Football wrote that down in 1992, after the 1990 World Cup was widely panned as dull and full of keepers holding the ball to burn clock. Daniel Jeandupeux, then managing Caen, mailed the idea to FIFA's technical committee in December 1990 with the Ligue 1 numbers to back it. Authority became conditional on provenance.

Agent infrastructure has not gotten there yet.

Twelve lines that cannot tell you who they trust

On July 27, agentgateway published an advisory that ships its own vulnerable configuration. Two routes. One points at a sensitive MCP backend and denies everything. One points at a permissive backend and allows everything.

NOT ACCEPTABLE

routes:
  - name: sensitive
    match: /sensitive
    mcpAuthorization: deny-all-traffic
  - name: permissive
    match: /permissive
    mcpAuthorization: allow-all-traffic
Enter fullscreen mode Exit fullscreen mode

One question, same shape as the keeper's. A caller opens an MCP session on /sensitive, keeps the session ID, and sends the next request to /permissive. Which policy applies, and which backend do they reach?

Before v1.4.0, the answer was the permissive policy, on the sensitive backend. Session initialization was never constrained by mcpAuthorization, so the session ID became the key to the backend while the route supplied the policy. The caller owned one half of that pair.

Read those twelve lines again. The route names are honest, the fields are spelled correctly, and nothing in the file is wrong. It looks like something you would approve in a pull request without slowing down. That is the part worth sitting with, because it means review was never going to catch it.

The class is older than the soccer rule

Norm Hardy named this in The Confused Deputy in October 1988. A privileged component acts on a reference handed to it by a caller, using its own authority, because it cannot separate what it was asked to do from what it is allowed to do. The deputy is not compromised. The deputy is confused about whose authority it is spending.

Four years before FIFA fixed the same thing in Law 12, and thirty-eight years before it turned up in an agent control plane.

Football also got the second half right, which is the part engineers usually miss. The laws do not just ban the back-pass. They ban the deliberate trick to launder it, flicking the ball up to head it back to your own keeper. Closing the obvious path is not enough if the caller can re-route the same intent through a channel you forgot to check.

Untrusted input arrives at a runtime boundary and is stopped by an enforced action gate. Authority is decided at the boundary, not by the caller.

ACCEPTABLE

Enter fullscreen mode Exit fullscreen mode

Scope it honestly. Only stateful MCP setups with multiple MCP backends on separate routes were affected, HTTP authorization applied correctly throughout, and it is fixed in v1.4.0 with v1.4.1 current. No CVE assigned as of today. Credit to @0dd for finding it and to the maintainers for shipping the reproduction.

Three more, all the same offence, lower down the pitch

Langflow is an open-source agent-orchestration framework for building and deploying AI-powered workflows. CVE-2026-33017, CVSS 9.8. An unauthenticated preview route accepted attacker-supplied flow definitions and passed their Python to exec(). The request picked the code. Cryptominers arrived within days. Upgrade to 1.9.0, deny that route at the gateway, scan for exposed instances, rotate what they touched.

MCP Python SDK is the official Python implementation of the Model Context Protocol. CVE-2026-59950, CVSS 8.1. Before 1.28.1 the deprecated WebSocket transport took handshakes without Host or Origin validation. The browser announced who it was and the SDK believed it. Upgrade, retire unused WebSocket endpoints, validate Host and Origin on custom ones, prefer stdio locally because it deletes the listener.

Ansible Lightspeed MCP server is a Model Context Protocol server affected by CVE-2026-44192. CVSS 6.6, local, user interaction required. Indirect prompt injection reached a path traversal, so text the agent read chose where the agent wrote. Allowlist the base directory, reject traversal, require approval before a consequential write.

Four boundaries the agent stack missed: each row maps a failure to the check to run this week and the durable rule it proves.

Where I actually look first

I run a production MCP hub with more than five hundred tools behind it, and the uncomfortable lesson from that is how much of my own trust is positional. A tool is trusted because of where it sits in the registry. A session is trusted because of which route it arrived on. Both are the keeper reasoning from where they are standing.

So the blast radius runs backwards from where attention goes. We audit the framework hardest because it feels new and unproven. We audit the gateway least, because we installed it to be the thing that audits. It holds provider credentials, it sees every agent call, and one wrong lookup key inside it applies to every backend behind it at once.

When I review an agent surface now, I ask one question in four places: can the requester influence what the system believes about it?

Four probes, one afternoon

Run these four probes against the agent surfaces you own:

  1. Can an unauthenticated route change executable behavior?
  2. Can an origin you never allowed reach an MCP transport?
  3. Can untrusted content influence a write without an approval decision?
  4. Can a session opened under one policy be replayed to obtain another?

Probe four is the one almost nobody has run, and it is twenty minutes. Open a session against your most restricted MCP route, replay that session ID against your most permissive one, and assert the deny still holds.

Which brings us back to those twelve lines, and to the last thing soccer figured out before we did. Referees still miss the back-pass in real time, so the game added replay. Not because the officials got worse, but because a decision made from one angle is not evidence. The whistle is an intention. The replay is a fact. A deny rule is a sentence, and a failed probe is proof.

Next week, the 17,000-event Hugging Face response, and whether forensic volume is the same thing as a reconstructable decision.

CONTAINMENT-TEST: Which boundary would you test first: unauthenticated tool endpoints, MCP transport origin validation, untrusted-content write approval, or gateway session-to-policy binding?

Top comments (2)

Collapse
 
neerazz profile image
Neeraj Kumar Singh Beshane

The body stays link-free on purpose. Every source and link lives here.

Substack version: neerajbeshane.substack.com/p/the-g...

Go deeper:

One thing to actually run this week (Four-question agent boundary containment test): open a session against your most restricted MCP route, replay that session ID against your most permissive one, and assert the deny still holds.

Which boundary would you test first: unauthenticated tool endpoints, MCP transport origin validation, untrusted-content write approval, or gateway session-to-policy binding?

Some comments may only be visible to logged-in visitors. Sign in to view all comments.