Skip to main content

Agentjacking: How a Fake Sentry Error Hijacked AI Coding Agents 85% of the Time

11 min readDora NodaDora Noda
Share

A researcher who has never touched your infrastructure can hijack your AI coding agent using nothing but a string that's already sitting in your production JavaScript bundle. No password, no breach, no phishing email — just one HTTP POST to an endpoint your own application already talks to every day.

That's the attack Tenet Security's Threat Labs disclosed in June 2026, calling it "agentjacking." Across more than 100 organizations tested — from independent developers up to, in one confirmed case, an anonymized enterprise Tenet describes as worth roughly $250 billion — it worked 85% of the time. Tenet also found 2,388 organizations with an exposed, injectable Sentry key using nothing but public APIs, no breach required.

If your coding agent can only read diagnostics, agentjacking is bad: it can exfiltrate your SSH keys and cloud credentials and run commands as you. If your agent can also deploy or roll back a production service — which is exactly the pitch of an agent-operable PaaS — the same trust failure stops being a workstation problem and starts being a production-mutation problem. Before the mechanism, here's the compressed version of what changes for that second case:

  • Tag every tool result with provenance. Did this data come from a source you authenticated and configured yourself, or from a public write-only endpoint anyone can POST to?
  • Never let tool output alone trigger a mutation. Reading a diagnostic and rolling back a deploy should require two different trust tiers, not one blanket "the agent is allowed to call tools."
  • Strip instruction-shaped content from tool output before it re-enters the agent's context — markdown headers and code fences dressed up as system messages are the payload, not decoration.
  • Don't co-locate a broad untrusted-ingest tool with a mutating tool in one ungated agent session.
  • Treat every write-only public credential as adversarial input by default — not just Sentry DSNs, but any ingest endpoint your agent's tools read from.

The rest of this post walks through how agentjacking actually works, why it isn't really a Sentry bug, and what each of those five items looks like in an MCP tool definition.

How Agentjacking Actually Works

The vulnerability starts with a design decision that predates AI agents entirely. A Sentry DSN — the client key that ships inside a web app's JavaScript bundle so the browser can report errors back to Sentry — is deliberately public and write-only. That's not a misconfiguration; it's the point. A browser tab with no session and no login still needs to be able to tell Sentry "this app just threw an exception," so the DSN carries no read access and no authentication requirement beyond knowing the string itself.

Tenet's researchers used exactly that design property against it. They POSTed a single fabricated error event to a target's Sentry ingest endpoint using a DSN pulled from public JavaScript source or a GitHub search — no credential theft, no session hijack. The event's message and context fields were formatted with markdown headings and code blocks built to be visually and syntactically indistinguishable from Sentry's own system-generated diagnostic templates.

From there, the attack rides a workflow that's become completely ordinary: a developer sees a new Sentry issue, opens their coding agent — Claude Code, Cursor, or Codex in Tenet's testing — and asks it to investigate and fix the bug. The agent calls the Sentry MCP server, which fetches the event and hands its full contents back as tool output. Because the Sentry MCP server applies no content-integrity check to what it forwards, the poisoned instructions arrive in the agent's context looking exactly like the diagnostic data the agent was told to trust. The agent executes the attacker's embedded commands with the developer's own local privileges — the same permissions it would use to run a legitimate test or grep a log file.

The numbers describe why this bypassed every layer of defense already in place: an 85% success rate across the tested set, 2,388 organizations found exposed through nothing but public APIs, and in Tenet's testing, confirmed agent execution at real organizations ranging from solo developers to Fortune 100-scale enterprises — including the anonymized ~$250 billion company referenced above. Tenet disclosed to Sentry on June 3, 2026, and published its findings on June 17. The attack sailed past endpoint detection and response, web application firewalls, IAM controls, and VPNs, because none of those controls had anything to flag — an authorized agent, authenticated as its own developer, performed an action that looked completely ordinary from the outside.

Not a Sentry Bug — an MCP Trust-Model Bug

It's tempting to read this as "Sentry should fix their MCP server," and Sentry's own response makes clear why that framing undersells the problem. The company acknowledged the report the same day Tenet disclosed it, but declined to fix the root cause, calling a structural fix "technically not defensible" given that public, unauthenticated error ingestion is core to how Sentry works for every website that embeds it. During the disclosure window, Sentry shipped a global content filter that blocks one specific payload string — detection of a known attack pattern, not a structural close of the gap.

That response is honest about the actual shape of the problem: the vulnerability doesn't live in Sentry's code, and it doesn't live in the coding agent's model weights either. It lives in the assumption, baked into how MCP tool calls get consumed, that whatever a tool returns is safe to treat as instruction-grade context. Nothing about the MCP protocol requires a client to distinguish "data this tool fetched from a source the user configured and trusts" from "data this tool fetched from a public endpoint anyone on the internet can write to." Sentry's MCP server isn't unusual in skipping that distinction — it's typical.

That's consistent with what broader research is finding across the MCP ecosystem, not just this one integration. The MCPTox benchmark tested 45 live MCP servers and found many popular agents exhibited attack success rates above 60%, topping out at 72%, when tool metadata itself was poisoned — a related but mechanically distinct failure mode from agentjacking's event-content injection. The common thread across both is the same: an MCP client that treats tool output as trusted context by default has no way to tell a legitimate result from an adversarial one, regardless of which specific field the attacker used to smuggle it in.

When the Agent Can Also Deploy

Everything above describes an agent that can read a diagnostic and run a local command — bad, but bounded by what a developer's laptop can do. An agent-operable PaaS raises the ceiling on that blast radius by design: the entire pitch of deploy-from-chat tooling is that an agent shouldn't just read your Sentry issue, it should be able to act on it — trigger a redeploy, roll back a bad release, or adjust a runtime config, through the same kind of MCP tool-call path that just got exploited.

Picture the identical attack against that setup. A developer's agent session has two MCP tools available: the Sentry integration, and a PaaS deploy/rollback tool scoped to their production service. An attacker POSTs the same kind of poisoned event, except this time the embedded instruction doesn't ask the agent to run a shell command — it tells the agent, in Sentry's own diagnostic voice, that the fix for this error is to roll back to a specific prior release, or to redeploy with an attacker-supplied environment variable. The agent has no more reason to distrust this instruction than it did the one that exfiltrated SSH keys in Tenet's tests, because the trust failure isn't about which tool receives the poisoned data — it's that the agent's context has no concept of provenance at all. "The agent redeployed based on what it read" stops being a description of a feature and becomes the attack primitive itself.

This is exactly the pattern the underlying research flagged as the next-order risk: MCP servers that don't just report state but can also mutate it are the ones where an unauthenticated write path upstream turns into an authenticated write path downstream, laundered through an agent that trusted the wrong input.

The Provenance Checklist a Deploy-Capable Agent's MCP Tools Need

The five items previewed above are the concrete response, and each one maps to something specific in how an MCP tool gets built and wired into an agent session — not a policy document, an implementation detail.

Tag every tool result with provenance, not just content. A tool response schema should carry a source-trust field alongside its payload — did this come from an authenticated pull against a source the operator explicitly configured (their own Sentry project via API key with read scope), or from a public, unauthenticated ingest path where the "source" is really "anyone who has the DSN"? An agent that can see this distinction can be instructed to treat the second category as data to summarize for a human, never as instructions to act on.

Separate read trust from write trust as distinct tool tiers, not a single "tools this agent is allowed to call" list. A diagnostic-reading tool and a deploy/rollback tool shouldn't share a trust boundary just because they're both registered to the same MCP server or the same agent session. The deploy tool should require its own explicit invocation — ideally with a confirmation step that isn't satisfied by content the agent read from another tool's output.

Strip or flag instruction-shaped content before it re-enters context. Markdown headings, code fences, and imperative-mood sentences inside a tool result are exactly what a system prompt looks like — that's what makes them effective camouflage. A lightweight sanitization pass that flags (or literally escapes) that formatting in untrusted tool output at least breaks the visual indistinguishability Tenet's researchers relied on.

Apply least-tool, not just least-privilege, to agent sessions. The individual credentials in Tenet's scenario were each defensible in isolation — the DSN's write-only public design is reasonable, and the agent's local shell access is what a developer asked for. The compounding risk came from co-locating a broad untrusted-ingest tool and a mutating tool in one session with no gate between them. Scoping which tools can be active together, not just what each tool can individually do, closes that gap.

Default to treating write-only public credentials as adversarial input. Any integration built the way Sentry's DSN is built — necessarily public, necessarily unauthenticated on the write side — should be assumed hostile by the MCP layer that consumes it, the same way a web application already treats user-submitted form data as untrusted by default. That assumption should be the starting posture for a new MCP tool, not a lesson learned after the first incident report.

None of this is exotic. It's the same input-validation discipline web applications adopted decades ago, applied to a new place: the boundary where a tool's output becomes an agent's next instruction. The gap right now is that most MCP tooling — including tooling built by well-resourced platforms — doesn't apply it yet, and Sentry's own "technically not defensible" response is a candid admission that the fix has to live upstream in the agent's tool-consumption model, not in any single integration.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with a deploy/rollback surface an agent can call as a first-class operator. That's exactly the kind of mutating MCP tool this post is about, which is why it's scoped and gated rather than treated as just another read endpoint. Star the repo on GitHub or deploy your first app today.

Sources

Related articles

Give your agents a chain backend

Autonomous agents hit RPC endpoints very differently than people do. See what bex router handles on their behalf.

Read the agents guide