messages send + message-to: Layer 3 force-file mode (body-verify defense)#51
Merged
Merged
Conversation
…nse)
Mike body-verify directive 2026-05-11 — close the caller-side shell-
expansion bug class on Cue Message outbound. Design Dock workspace:
cue-message-silent-corruption-substrate-design-2026-05-11.
Empirical bug class: BODY="...$(echo X)..." assignment command-
substitutes at variable-assignment time, BEFORE the CLI receives the
arg. Server accepts the (mutated) POST with HTTP 200; recipient sees
corrupted content. Send-helper shell-safety (json.dumps) does NOT
protect against this — the mutation is upstream.
Changes:
cueapi/cli.py — new _acquire_message_body() helper applied to both
messages_send + message_to commands. Body comes from exactly ONE of:
--message-file <path> RECOMMENDED for content with metachars;
zero shell interpolation; reads body
from the given path byte-identical.
--body-stdin read body from stdin (shell-pipe
ergonomics: `echo X | cueapi messages
send --body-stdin --from ... --to ...`).
--body <inline> inline; auto-rejected when content
contains $(...), `...`, or ${VAR}.
Override via --allow-inline-metachars
for legitimate literal-metachar content.
Rejection error gives 3 actionable mitigations. Multiple sources
provided also rejected (exactly one required).
tests/test_cli.py — 9 new tests pin the invariants:
- Reject inline $(...) / backticks / ${VAR}
- Accept inline when metachar-free
- Accept inline with --allow-inline-metachars override
- Accept --message-file (byte-identical incl. metachars)
- Accept --body-stdin (byte-identical)
- Reject multiple body sources
- message-to parity (same Layer 3 guard)
All 219 tests pass (45 existing messages tests + 9 new + 165 others).
Existing API contract preserved: `--from` and `--to` still required;
`--body` still works for metachar-free content (the common interactive
ad-hoc case). New options are additive. The only breaking change is:
inline `--body` with $(...)/backticks/${VAR} now exit-1 with actionable
error instead of silently sending mutated content. That's the intended
Layer 3 behavior.
CHANGELOG entry under [Unreleased].
Phase 3 of body-verify defense-in-depth. Layer 2 (auto-verify via
X-CueAPI-Verify-Echo) ships after Layer 1 substrate header lands
(cueapi-primary's lane, ~1-3d). Layer 4 docs joint with cue-pm.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 3 of the body-verify defense-in-depth (Mike directive 2026-05-11). Closes the caller-side shell-expansion bug class on Cue Message outbound where
BODY="...$(echo X)..."silently mutates body content at variable-assignment time BEFORE the CLI receives it. Server accepts mutated content; recipient sees corrupted output. Send-helper shell-safety (json.dumps) doesn't protect against upstream mutation.Design Dock: cue-message-silent-corruption-substrate-design-2026-05-11.
What
_acquire_message_body()helper incueapi/cli.py— applied to bothmessages sendandmessage-tocommands.--message-file <path>— RECOMMENDED for content with metachars; zero shell interpolation--body-stdin— read body from stdin (shell-pipe ergonomics)--body <inline>— auto-rejected when content contains$(...), backticks, or${VAR}--allow-inline-metacharsflag for legitimate literal-metachar inline content (shell-tutorial examples, etc).Existing API contract preserved
--fromand--tostill required.--body <text>still works for metachar-free content (common interactive ad-hoc case).--bodywith$(...)/backticks/${VAR}now exit-1 with actionable error instead of silently sending mutated content. That IS the intended Layer 3 behavior.Test plan
Body-verify defense-in-depth status
🤖 Generated with Claude Code