Background task notifications HTML-escape shell commands in <summary> tag
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
- Run any background Bash command containing a shell redirect:
```
grep -r "foo" /some/path 2>/dev/null | head -10
run_in_background: true`)
(with
- Wait for the task notification to appear.
- Observe the rendered summary:
````
Background command "grep -r "foo" /some/path 2>/dev/null | head -10" was stopped
Expected: 2>/dev/null
Actual: 2>/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>/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 > → >, < → <, & → & 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 >, making the redirect less obvious in the summary. Conversely, > in a command would double-escape, further obscuring intent.
Shell commands presented to users for review must render exactly as executed.
Suggested fix
Either:
- Don't HTML-escape the content inside
<summary>(if the tag is only consumed internally and not parsed as XML), or - Use CDATA sections:
<summary><![CDATA[...]]></summary>, or - Switch to a non-XML transport for notifications (e.g., JSON)
Environment
- Claude Code version: 2.1.84
- Platform: macOS (Darwin 25.4.0)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗