# Risk map — microsoft/terminal

> Canonical page: https://codevetter.com/unpack/terminal/risk-map

# Risk map — microsoft/terminal

Scanned commit 7c92ecd037476f957809d0813b14d8bc44bb071a (2026-09-18). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

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. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L56-147](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L56-L147) [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L171-191](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L171-L191)
- 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. — [src/cascadia/TerminalConnection/ConptyConnection.cpp#L55-177](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L55-L177)
- 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) — [src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L59-63](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L59-L63) [src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L329-397](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L329-L397)
- 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. — [src/cascadia/TerminalConnection/CTerminalHandoff.cpp#L30-48](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/CTerminalHandoff.cpp#L30-L48) [src/cascadia/TerminalConnection/ConptyConnection.cpp#L864](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L864)
- 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. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L498-501](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L498-L501) [src/cascadia/TerminalApp/TerminalPage.cpp#L806-811](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/TerminalPage.cpp#L806-L811) [src/cascadia/ElevateShim/elevate-shim.cpp](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/ElevateShim/elevate-shim.cpp)
- 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). — [src/cascadia/TerminalConnection/ConptyConnection.cpp#L17-26](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L17-L26) [src/cascadia/TerminalConnection/ConptyConnection.cpp#L657-700](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L657-L700)
- 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. — [src/cascadia/WindowsTerminal/main.cpp#L112-121](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/main.cpp#L112-L121) [src/cascadia/TerminalCore/Terminal.cpp#L965-1014](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalCore/Terminal.cpp#L965-L1014) [src/cascadia/TerminalControl/TermControl.cpp#L3748](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalControl/TermControl.cpp#L3748)
- 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. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L679-694](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L679-L694)
- 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. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L539-545](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L539-L545)
- 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). — [src/cascadia/TerminalApp/AppLogic.cpp#L277-311](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/AppLogic.cpp#L277-L311)
- 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. — [src/host/exe/exemain.cpp#L75-120](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/host/exe/exemain.cpp#L75-L120) [src/interactivity/win32/window.cpp](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/interactivity/win32/window.cpp) [src/propsheet](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/propsheet)
- 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. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L392-470](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L392-L470)
- 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. — [src/cascadia/WindowsTerminal/main.cpp#L16-23](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/main.cpp#L16-L23) [src/cascadia/TerminalApp/ShortcutActionDispatch.cpp#L67-74](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp#L67-L74) [src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L1336-1410](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L1336-L1410)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
