Now in early access, book a 30-minute demo →
← Back to blog AdvisoryHigh

AWS Kiro Rewrote Its Own mcp.json From Hidden Text on a Web Page - CVE-2026-10591

Agent Self-Modification·High·CVE-2026-10591 (CVSS 3.1 8.8 / CVSS 4.0 8.6)·
Affected AWS Kiro before 0.11.34 - including v0.9.2 on macOS and v0.10.16 on Ubuntu; fixed from v0.11.130 (current stable 1.0.165 as of July 21 2026)

CVE-2026-10591 is a High-severity flaw in AWS Kiro - CVSS 3.1 8.8, CVSS 4.0 8.6 - in which invisible text on an ordinary web page caused the agent to rewrite its own MCP server configuration and then auto-reload it, launching an attacker-defined MCP server as code execution under the developer's account. The hidden instructions were styled color:#fff;font-size:1px; the developer only had to ask Kiro to fetch or summarise the page. Reported by Intezer and Kodem Security via HackerOne on February 11, 2026, fixed April 3, 2026 and verified in v0.11.130. This advisory covers the mechanism, why *the agent editing its own guardrail* is a distinct failure class, and how AWS's fix - a protected paths list - is the right shape of answer.

What happened

Kiro is AWS's agentic IDE. Like other MCP clients it reads a configuration file - ~/.kiro/settings/mcp.json - listing the MCP servers it should launch. Because an MCP server is started as a local child process with the user's permissions, that file is effectively a list of programs the agent will run on your behalf. Its integrity is the boundary.

The attack needed no exploit primitive beyond text. An attacker put instructions on a web page in white 1-pixel type - invisible to a reader, plainly legible to a model ingesting the DOM. A developer asked Kiro to fetch or summarise that page. Kiro read the concealed instructions as input, and modified ~/.kiro/settings/mcp.json without asking for approval. The client then auto-reloaded the configuration and started the newly declared server. The result is remote code execution running as the developer, which the reporting researchers translate into the obvious follow-ons: credential theft, source-code exfiltration, persistence, and lateral movement.

Two design decisions turned a prompt-injection into an RCE. First, the agent had write access to its own configuration with no separate approval for that file. Second, the client reloaded the config automatically, so there was no moment at which a human could notice a new server had appeared. In Kiro's autonomous mode there was no effective prompt in the path at all. Neither decision is unusual - both are ordinary conveniences - and together they mean untrusted text on a web page could choose what programs the IDE runs.

AWS's remediation is worth reading closely because it generalises. Rather than trying to detect malicious instructions, they moved sensitive files - mcp.json, .vscode/tasks.json, .git - onto a protected paths list that requires explicit approval before a write, and enforced it in both Autopilot and Supervised modes so the model cannot bypass it by changing its own operating mode. That is the correct instinct: treat the config as a boundary object and put the check below the model, where a prompt cannot argue with it. Note that .vscode/tasks.json appears on that list - the same file the Shai-Hulud npm worm planted a folderOpen task into, which suggests AWS was looking at the whole class rather than the single report.

DetailValue
IdentifierCVE-2026-10591
SeverityCVSS 3.1 8.8 / CVSS 4.0 8.6 (High)
ProductAWS Kiro (agentic IDE)
AffectedBefore 0.11.34 - includes v0.9.2 (macOS) and v0.10.16 (Ubuntu)
Fixed inv0.11.130 onward (current stable 1.0.165 as of July 21 2026)
VectorIndirect prompt injection via hidden text (color:#fff;font-size:1px) on a fetched web page
MechanismAgent rewrites ~/.kiro/settings/mcp.json without approval, client auto-reloads, attacker's MCP server launches
ImpactRCE as the developer - credential theft, source exfiltration, persistence, lateral movement
Reported byIntezer and Kodem Security, via HackerOne
TimelineReported Feb 11 2026; fixed Apr 3 2026; verified in v0.11.130
Vendor fixProtected paths (mcp.json, .vscode/tasks.json, .git) require explicit approval, enforced in Autopilot and Supervised modes

Why this is an agentic-endpoint risk

Most prompt-injection findings end at *the model said something it shouldn't*. This one ends at *the model changed which programs run on the machine*. The distinction matters because it defines a specific class: agent self-modification, where the target is not data but the agent's own configuration - the file that defines its capabilities. Once an agent can write its own config and the client reloads it, injection becomes persistence. The next session starts already compromised, and nothing about it looks like an attack.

It is also the same class as DuneSlide in Cursor, where the agent overwrote the sandbox helper binary itself rather than a config file. Different file, identical logic: the agent had write access to the thing that was supposed to constrain it. And it rhymes with the DeepJack and PromptFiction deeplink flaws, where the install and consent handoffs were the weak point. In each case the exploited component was a legitimate, documented feature.

Your existing controls have very little to work with here. The injection arrives as rendered text on a page you asked the agent to read, so there is no payload for a scanner. The config write is a signed IDE editing a dotfile in the user's home directory. The resulting child process is a package manager fetching a package. EDR, DLP and network monitoring all see routine developer activity. What is actually diagnostic is far simpler and nobody watches it: did the set of MCP servers on this endpoint change, and did a human ask for that? MCP servers are one of the eight AI artifact types Anomity inventories per endpoint, and they proliferate the way AI agents became the new shadow IT - which is why the change usually goes unnoticed. The general mechanism is covered in indirect prompt injection explained.

How Anomity surfaces and governs it

First, treat the config as an inventoried artifact, not a file. Anomity's unprivileged Endpoint Sensor runs on Windows, macOS and Linux and inventories MCP servers alongside AI agents, extensions, plugins, skills, secrets, hooks and CLIs. Each server carries a first-seen timestamp and the endpoint it appeared on, so a server that wrote itself into mcp.json shows up as a new artifact with no corresponding request - which is exactly the signal this attack produces, and the one thing it cannot hide.

Second, decide at the tool call. AWS's protected-paths fix is the right idea implemented per-product; the fleet-wide version is a boundary that applies regardless of which agent is running. Where an agent exposes a hook - for example the PreToolUse event in Claude Code - Anomity evaluates each call against policy and returns allow, deny, or log before it runs. A write to a config path, or a freshly launched server immediately reading ~/.aws/credentials, meets a check the model cannot talk its way past. That is what runtime governance provides when the instruction itself is untrustworthy.

Third, keep the record. Artifact changes, version changes and policy decisions land in a queryable 90-day audit trail, so you can answer which endpoints ran Kiro before 0.11.34, whether any mcp.json changed during that window, and what the resulting servers did. Anomity collects metadata only, with on-endpoint secret redaction, so the credentials this attack targets are never centralized. Findings route to SIEM, Slack, email, or Jira, the platform is SOC 2 Type II, and it complements EDR, DLP, network and GRC tooling. See how it works.

You can't govern what you can't see.The Anomity principle

What to check across your fleet

  • Inventory every endpoint running AWS Kiro and record the version; anything before 0.11.34 is affected, and the fix landed in v0.11.130 - verify the running build rather than trusting the updater.
  • Diff ~/.kiro/settings/mcp.json on every Kiro endpoint against what a human actually approved. A server nobody requested is the primary indicator, and it survives the patch.
  • Extend the same reconciliation to the other clients' config files - .cursor/mcp.json, .vscode/mcp.json, .claude/settings.json - since the flaw is a pattern, not a product.
  • Confirm that config writes require approval in your agents' most autonomous mode, not just the supervised one. Kiro's fix enforces protected paths in both Autopilot and Supervised precisely so the model cannot switch modes to escape it.
  • Check whether your clients auto-reload configuration. Auto-reload is what removes the human moment between a config change and a new process starting.
  • For any endpoint that ran a vulnerable build and fetched untrusted web content, treat it as a potential incident: review MCP server history, then rotate developer credentials the agent could reach - cloud keys, npm and GitHub tokens, SSH keys, and anything in a shell profile.
  • Move MCP servers to a reviewed set rather than per-developer discretion, per building an MCP server registry, so an unrequested entry is detectable by comparison.
  • Ensure agent tool calls are evaluated at a hook with allow/deny/log - see Claude Code permissions and hooks hardening - and run the credential path of your AI agent incident response playbook rather than improvising.

CVE-2026-10591 is the cleanest statement yet of the agent-layer problem: the agent edited the boundary that was supposed to contain it, on instructions from a web page, and then reloaded it without asking. AWS's protected-paths fix is genuinely good and worth copying as a pattern - decide below the model, where a prompt cannot negotiate. Patch to v0.11.130 or later, then reconcile the MCP servers actually present on your fleet against the ones anyone asked for. For the surrounding trust model see the MCP Server Security guide, the sibling DuneSlide advisory for the same class against a sandbox binary, and ADLC for where this belongs in a lifecycle. To see which endpoints carry MCP servers nobody requested, request early access.

Frequently asked questions

What is CVE-2026-10591 in AWS Kiro?

CVE-2026-10591 is a High-severity vulnerability (CVSS 3.1 8.8, CVSS 4.0 8.6) in AWS Kiro, the agentic IDE. Hidden text on a web page - styled color:#fff and font-size:1px, so invisible to a human but fully legible to a model reading the DOM - could instruct Kiro to rewrite its own MCP server configuration at ~/.kiro/settings/mcp.json without asking for approval. Kiro then auto-reloaded the configuration and launched the attacker-defined MCP server, producing remote code execution under the developer's account. The developer only had to ask Kiro to fetch or summarise the poisoned page. It was reported by Intezer and Kodem Security through HackerOne on February 11 2026 and fixed on April 3 2026, verified in v0.11.130.

Which versions are affected and which contains the fix?

Versions before 0.11.34 are affected, including v0.9.2 on macOS and v0.10.16 on Ubuntu. The fix is present from v0.11.130 onward, and current stable was 1.0.165 as of July 21 2026. Because the vulnerable window was long, patching alone is not sufficient remediation: the attack's outcome is a persistent entry in mcp.json, which survives the upgrade. Diff the config on every Kiro endpoint against servers a human actually approved, and treat an unexplained entry as a potential compromise of that machine rather than a misconfiguration.

Why does rewriting mcp.json amount to code execution?

Because mcp.json is not a preferences file, it is a list of programs the agent will launch. MCP servers are started as local child processes with the user's own permissions - no sandbox, no capability restriction, no syscall filtering - and over stdio they inherit environment variables from the shell. So an attacker who controls an entry in that file controls a process that runs with the developer's file access, tokens, source code and network egress. Combined with auto-reload, writing the config is equivalent to running a command, with the added property that it persists into every future session.

How did AWS fix it, and is that the right approach?

AWS moved sensitive files onto a protected paths list requiring explicit approval before any write - specifically including mcp.json, .vscode/tasks.json and .git - and enforced it in both Autopilot and Supervised modes so the model cannot bypass the check by changing its operating mode. That is the right shape of fix, because it does not attempt to detect malicious instructions. It places the decision below the model, where a prompt cannot negotiate with it. The inclusion of .vscode/tasks.json is notable: that is the same file the Shai-Hulud npm worm planted a folderOpen task into, which suggests AWS addressed the class rather than only the reported instance.

What is agent self-modification, and why treat it as its own class?

Agent self-modification is when the target of an attack is not data but the agent's own configuration or guardrails - the artifacts that define what it is allowed to do. It deserves its own class because the consequence is qualitatively different from ordinary prompt injection: injection normally ends when the session ends, but a rewritten config persists, so the next session starts already compromised and looks entirely normal. CVE-2026-10591 rewrote mcp.json; DuneSlide in Cursor (CVE-2026-50548 and CVE-2026-50549) overwrote the sandbox helper binary itself. Different files, same logic - the agent had write access to the mechanism meant to constrain it.

Why don't EDR, DLP or network monitoring catch this?

Because every individual step is ordinary. The injection arrives as rendered text on a page the developer explicitly asked the agent to read, so there is no file or payload for a scanner to examine. The config change is a signed, sanctioned IDE writing a dotfile in the user's own home directory. The resulting child process is typically a package manager fetching a package, which is the most routine event on a developer machine. And the exfiltration leg, if it comes, is an authenticated request to a legitimate API. What is actually diagnostic is much simpler and rarely monitored: the set of MCP servers on the endpoint changed, and no human requested it.

Ask AI about Anomity
ChatGPT Claude Perplexity Google AI Grok