Skip to content

[VT][Security] OSC 52 clipboard write #252

Description

@benyblack

Not a first issue — the security posture is the hard part, not the parsing. Read CONTRIBUTING.md § How Much Ceremony Your Change Needs first; this is a core change.

Context

docs/vt_coverage_matrix.md:145 marks OSC 52 as ❌ Not supported. It is what lets a program running over SSH copy to your local clipboard — the most requested remote-workflow feature in terminals, and both tmux and nvim drive it.

What to change

OSC 52 ; Pc ; Pd ST, dispatched from HandleOsc at src/NovaTerminal.VT/AnsiParser.cs:1465 (follow the OSC 0/2 and OSC 7 shape at :1496-1514).

Architecture constraint: the VT core must not depend on UI or OS — see CONTRIBUTING.md § Architectural Rules and docs/MODULE_OWNERSHIP.md. So the parser raises an event — OnClipboardWriteRequested alongside the existing OnTitleChanged / OnWorkingDirectoryChanged — and the App layer performs the clipboard write. A PR that reaches for an Avalonia clipboard API from inside NovaTerminal.VT will be sent back, and tests/NovaTerminal.Architecture.Tests/LayeringTests.cs will tell you before a reviewer does.

Security posture, which is the substance of this issue:

  • Reads (Pd = ?) must be refused. A remote process being able to read your clipboard is an exfiltration primitive — passwords, tokens. xterm ships this disabled for good reason. Refuse it outright; do not add a setting for it in this PR.
  • Cap the payload. Base64 from a hostile source is unbounded. Pick a limit (xterm's is in the low hundreds of KB), enforce it before decoding, and drop oversized requests silently.
  • Validate the base64 strictly and drop malformed payloads rather than writing partial data.
  • Handle Pcc, p, s, 0-7, or empty. Mapping everything to the system clipboard is acceptable; mapping nothing is not.
  • Consider whether writes should be gated by a setting (default on) and whether a toast should confirm — a silent clipboard replacement from a background pane is surprising. Worth discussing in this thread before implementing.

How to test

tests/NovaTerminal.VT.Tests/ for the parse and policy layer — the event fires with decoded content for a valid write, and does not fire for a read request, an oversized payload, or malformed base64. Then update docs/vt_coverage_matrix.md and regenerate the conformance report (§ Changing VT Coverage).

Acceptance

  • Write path works end to end, event-based, no UI dependency in VT
  • Read requests refused, with a test pinning that
  • Size cap and base64 validation, with tests
  • Coverage matrix updated from to its real status

Files: src/NovaTerminal.VT/AnsiParser.cs, App-layer clipboard wiring, docs/vt_coverage_matrix.md, tests/NovaTerminal.VT.Tests/

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is neededsecurityvtVT/ANSI parser, buffer, reflow — NovaTerminal.VT

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions