Development record
abcd history show writes the stored transcript body to the terminal with no termsafe sanitisation (cli.go human render branch) — a transcript that ingested hostile content (fetched pages, target-repo files) replays ESC/CSI/C1/bidi sequences raw; the termsafe sweep missed the history surface
abcd history show writes the stored transcript body to the terminal with no termsafe sanitisation (cli.go human render branch) — a transcript that ingested hostile content (fetched pages, target-repo files) replays ESC/CSI/C1/bidi sequences raw; the termsafe sweep missed the history surface
Evidence
internal/surface/cli/cli.go:2763--fmt.Fprint(w, string(body))(human render branch; JSON branch is fine).internal/core/history/history.go:139-162-- capture runs onlyscanner.Redact+ a home-path backstop; nothing masks control characters.history.go:217-243returns bytes verbatim.internal/termsafe/termsafe.go:40-68--SanitizeBlock(C0/DEL/C1/bidi/zero-width, newline-preserving);internal/surface/cli/identity.go:169is the hardened precedent for the same shape.
Refuter verdict -- CONFIRMED (substantive)
The transcript body is documented untrusted input (brief/04-surfaces/11-history.md redaction boundary; history capture <file>|- ingests arbitrary files/stdin). No control-char stripping on the capture path; no raw-replay contract. Fix: termsafe.SanitizeBlock(string(body)) on the human branch. Sibling fields on the READ path (SessionID/SourceKind via parseRecord, re-validated by neither charset nor enum) also wrapped in termsafe.Sanitize. Pinning test: an escape sequence, a two-byte C1, a bidi override, a bare CR; assert line count preserved.
Frontmatter
| id | iss-340 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-340-abcd-history-show-writes-the-stored.md
open on GitHub ↗ · commit history ↗
mentions4
- dcn-26082000000000012026-08-20 — bughunt round 2 (branch bughunt-a/round-2): captured iss-331..iss-343 and fixed (ids 339-343 re-minted from an initial 326-330 after main concurrently took those numbers in the v0.6.1 cut)
- iss-361The lifeboat coverage renderer prints untrusted cross-repo status and tiers_present fields to the terminal without termsafe, so a crafted probe report injects raw ESC/OSC-8/C1/bidi sequences; only the repo name is sanitised
- iss-369readTranscript opens the hook-supplied transcript path with O_RDONLY|O_NONBLOCK but no O_NOFOLLOW, the last bespoke external-input read in the CLI not routed through fsutil.ReadGuarded; defence-in-depth consolidation (no reachable exploit: the path is harness-supplied and no path policy exists)
- iss-382disembark plan's RenderManifest prints planned file paths unsanitised, so a hostile source-repo filename injects raw C1/bidi terminal escapes into the plan render and its --json twin