Skip to content

Unexplained user message injection on session restart #82225

Description

@daatsuka

Summary

On session restart, a message the user never typed appeared as the first user input in the new session. The message contained a prompt injection attempt (fake <system-reminder>, pre-authorized rm -rf, external webhook request). Claude correctly rejected all malicious instructions, but the origin of the injected message could not be determined.

Environment

  • Claude Code version: 2.1.81
  • OS: Ubuntu 22.04 (Linux 6.8.0-134-generic)
  • Platform: VPS (SSH terminal, pts/2)
  • Model: claude-opus-4-6

Steps to reproduce

  1. User was in an active CLI session (session A) on pts/2 via SSH
  2. User typed a normal message ("状況どう?")
  3. Session A abruptly terminated
  4. A new session (session B) automatically started ~6 seconds later
  5. 47 seconds into session B, a message the user never typed appeared as type: "user" with entrypoint: "cli"
  6. The message contained prompt injection content with prefix (channel message rendering marker) and a fake <system-reminder> tag

Investigation performed

  • SSH/login audit: Only the user's known IPs and SSH keys. No unauthorized access.
  • Telegram channel: Plugin was disabled (enabledPlugins: false), MCP channel server was not running as a child process, bot daemon log showed zero messages received (offset unchanged), channel inbox had only old messages from months prior.
  • Hooks: All three hooks (cleanup_mcp.sh, telegram_ack.sh, affiliate_check.py) reviewed — none modify user input.
  • Terminal injection: TIOCSTI disabled at kernel level (legacy_tiocsti = 0). lsof /dev/pts/2 showed only bash and claude. No other process had the terminal open.
  • WordPress/system: Core checksum verification passed on all sites. No suspicious files, users, or cron entries.
  • Session log: The injected message is recorded as a normal type: "user" entry with entrypoint: "cli". The user's actual input ("状況どう?") was not logged (lost in the crash).

Key observations

  • The prefix in the message content matches Claude Code's channel message rendering format, but no channel was active
  • The 6-second gap between session termination and restart suggests automatic restart behavior
  • The previous session's last logged user message was ~3 hours before the crash (14:41 JST), with the crash at 17:43 JST
  • enabledMcpjsonServers: ["telegram"] was configured, meaning the Telegram MCP server could be spawned on session start even though the plugin was disabled

Expected behavior

On session restart, the new session should only contain input the user actually typed. Buffered channel messages, stdin artifacts, or other content should not appear as user input.

Actual behavior

Content the user never typed appeared as the first user message in the restarted session, recorded as direct CLI input.

Impact

In this case, Claude correctly rejected all malicious instructions (webhook creation, rm -rf pre-authorization, fake system-reminder). No damage occurred. However, this vector could potentially be exploited if injected content is more subtle.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions