Background task notifications HTML-escape shell commands in <summary> tag

Resolved 💬 3 comments Opened Mar 27, 2026 by fbartho Closed Mar 31, 2026

Summary

When a background Bash command completes (or is killed), the <task-notification> delivered to the conversation HTML-escapes shell metacharacters in the <summary> tag. The user sees a mangled command that doesn't match what was actually executed.

Reproduction

  1. Run any background Bash command containing a shell redirect:

``
grep -r "foo" /some/path 2>/dev/null | head -10
`
(with
run_in_background: true`)

  1. Wait for the task notification to appear.
  1. Observe the rendered summary:

``
Background command "grep -r "foo" /some/path 2&gt;/dev/null | head -10" was stopped
``

Expected: 2>/dev/null
Actual: 2&gt;/dev/null

Evidence from session log

The original tool call input contains the correct command:

{
  "command": "grep -r \"snap.new\\|snap\\.new\" /path/to/repo 2>/dev/null | head -10"
}

The notification summary contains the escaped version:

<summary>Background command "grep -r "snap.new\|snap\.new" /path/to/repo 2&gt;/dev/null | head -10" was stopped</summary>

Session log confirms the escaping happens between command execution and notification rendering — the command itself executed correctly, but the display is wrong.

Root cause

The CLI constructs <task-notification> using XML-like tags, and HTML-escapes the command string to make it XML-safe. This converts >&gt;, <&lt;, &&amp; inside the <summary> content.

Security concern

This is a presentational bug, but it has security implications. The <summary> is the canonical display of what was executed — it's what users rely on to verify that a background command did what they expected. Since the escaping is lossy/asymmetric:

  • The user sees a different string than what actually ran
  • The escaped characters (>, <, &) are precisely the shell metacharacters that control data flow — redirects, pipes, process substitution, backgrounding
  • An attacker aware of this behavior (e.g., via prompt injection in a fetched document) could craft commands where the escaped rendering looks benign or confusing enough that users don't notice the actual operation

For example, a command writing to a file via > would display with &gt;, making the redirect less obvious in the summary. Conversely, &gt; in a command would double-escape, further obscuring intent.

Shell commands presented to users for review must render exactly as executed.

Suggested fix

Either:

  1. Don't HTML-escape the content inside <summary> (if the tag is only consumed internally and not parsed as XML), or
  2. Use CDATA sections: <summary><![CDATA[...]]></summary>, or
  3. Switch to a non-XML transport for notifications (e.g., JSON)

Environment

  • Claude Code version: 2.1.84
  • Platform: macOS (Darwin 25.4.0)

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗