security: strip ANSI/OSC escapes from API-controlled output
Merged
JE
4mo ago+2117+2117+0123456789012345678901234567890123456789-128-128-012345678901234567890123456789
Strip ANSI/OSC escapes from API-controlled output
(Threat: T4 terminal injection via API-controlled strings carrying ANSI/OSC sequences.)
API-controlled strings (project/person/entity names, summaries, notices) reached lipgloss.Render/stdout and the --watch TUI without ansi.Strip, in render paths the generic table/cell path already protected.
Fix
- Sink-only: sanitize at every terminal sink, not at the source.
Summary/Notice/Diagnosticare stored verbatim byWithSummary/WithNotice/WithDiagnostic(so machine/JSON output preserves byte fidelity, consistent with error/hint/data) and stripped only where they're emitted to a terminal ā the styled and markdown renderers and the quiet-mode stderr diagnostic (render.go,envelope.go). --watchTUI: strip creator/action/title/excerpt + the person/project description (timeline.go); rune-truncation otherwise preserves escape bytes and the alt-screen executes OSC sequences.- Presenter: strip in
formatText/formatPerson/formatPeopleand the rendered affordance commands (presenter/format.go,presenter/render.go).
Tests
Tests assert JSON summary/notice are verbatim and that every terminal sink (styled/markdown/plain RenderError, summary/notice, breadcrumbs, attachment metadata, and the quiet-mode stderr notice:) neutralizes C1/CSI/OSC escapes.
Part 2/6 of the stacked security series. Base: security/01-api-token-leak.
š Stack (merge bottom-up)
- #478 ā reject foreign-host URLs in
api(basemain) - #479 ā strip ANSI/OSC escapes from output
- #480 ā harden OAuth discovery / token endpoints
- #481 ā close config trust-boundary gaps + completion gate
- #482 ā tighten config-dir perms + plugin scope argv
- #483 ā bump toolchain/x-net + CI gates
Each is independent except #482 depends on #481 (shared root.go). #478 can land first/alone.