CodeVetter · Repo Unpack · Risk map
microsoft/terminal
The riskiest areas are cross-process trust boundaries and lifecycle races. The WM_COPYDATA handoff sends the entire environment block (potentially containing secrets) to an existing instance and parses a remote buffer — bounds-checked, but a real IPC attack surface. ConPTY spawn uses raw CreateProcessW with expanded environment and user-controlled profile commandlines. The defterm COM handoff accepts duplicated handles from other processes. The codebase repeatedly documents fragile threading invariants (STA-before-XAML, recursive ticket lock, output-thread join on Close, XAML islands quirks) — these are blast-radius hotspots. Telemetry (TraceLogging with Microsoft telemetry options) is pervasive and warrants privacy review on changes.
- WM_COPYDATA handoff serializes the caller's full environment block (GetEnvironmentStringsW) into the message to the existing instance — any spawned wt.exe inherits and forwards env secrets; the receiving side parses remote memory via deserializeHandoffPayload/deserializeString with bounds checks.
- Process launch surface: profile 'commandline' strings from settings.json go through wil::ExpandEnvironmentStringsW and CreateProcessW with a mutable buffer and custom environment block; startingDirectory is WSL-mangled. Command lines are attacker-influenceable if a profile/fragment is malicious.
- Settings fragments: JSON files under other packages' 'Microsoft\Windows Terminal\Fragments' folders and registered app extensions are merged into the user's settings (profiles, schemes) during every load — a content injection path gated only by package identity. (inferred)
- COM defterm handoff: CTerminalHandoff registers a CLSCTX_LOCAL_SERVER class object that accepts in/out/signal/reference/process handles from arbitrary callers to adopt a PTY — trust boundary across processes.
- Elevation boundary is only the window-class-name/mutex namespacing (' Admin' suffix) plus forcing Elevate(false) on defterm tabs; the ElevateShim does the actual elevated spawn. Mixing elevated and non-elevated commandlines in one instance would be a security bug, so the class-name isolation is load-bearing.
- Termination is documented as fragile: ConptyConnection has an 'EXIT POINT' protocol for the three ways a connection dies (Close, spawn failure, pipe EOF) to avoid reentrant state flapping; Close() busy-loops CancelIoEx/WaitForSingleObject to guarantee no async TerminalOutput.raise after ControlCore teardown (GH#13880).
- Threading invariants are subtle and enforced by comments, not types: STA must precede all XAML objects (main.cpp '!!! LOAD BEARING !!!'), TerminalCore guards the buffer with a til::recursive_ticket_lock (LockForWriting) with suspend support, and TermControl warns about deadlocking when calling into ControlCore from event handlers.
- The single message loop hand-patches XAML deficiencies: F7 caret-browsing, Alt-keyup, and Alt+Space are intercepted before TranslateMessage/DispatchMessage — behavioral coupling that could break on WinUI updates.
- Process exit after command-line handoff uses TerminateProcess(0) 'primarily to avoid WinUI shutdown issues' — abrupt termination means destructors/finalizers never run; anything added after the handoff point must tolerate that.
- Settings watcher auto-reloads on ANY rename/write of a file named settings.json in the watched dir; malformed JSON keeps old settings but posts errors, and the code warns against holding a static ApplicationState ref in the callback because teardown ordering would crash (a real past bug pattern).
- conhost still carries the legacy console path: HKCU\Console\ForceV2=0 reverts to v1 console, and interactivity/win32 maintains classic window/menu/clipboard code — a large legacy surface kept alive for inbox compatibility.
- Registry/file probing at startup includes scanning the user's pinned-taskbar .lnk files (IShellLink/IPersistFile) to decide AUMID stamping — benign but a privacy-sensitive file enumeration on every unpackaged launch.
- Telemetry is pervasive: every component defines a TraceLogging provider with TraceLoggingOptionMicrosoftTelemetry and emits measure-keyworded events (ExeCreated, SessionBecameInteractive, ConPtyConnected, ActionDispatched, ThemesInUse) — changes touching these paths have privacy-review implications.