Skip to content

Open transcript URLs on modifier click - #964

Open
TheGreatAxios wants to merge 6 commits into
mainfrom
cl-7346-url-click-through
Open

Open transcript URLs on modifier click#964
TheGreatAxios wants to merge 6 commits into
mainfrom
cl-7346-url-click-through

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Collaborator

Summary

  • Holding the platform modifier over an http(s) URL in a transcript row underlines it, and releasing a press on the same URL opens it in the default browser
  • Plain clicks, drag selection, mouse-capture-off behavior, and non-http(s) targets behave exactly as before
  • Markdown prose stays terminal-owned, since its renderers expose no text-leaf API to highlight or hit-test

Verification

  • bun run typecheck, bun run build, and bun run check pass
  • New unit and transcript integration tests cover scheme gating, hit-testing, hover highlight, open-on-release, and unchanged plain-click behavior
  • Modifier reporting depends on the terminal sending key-modifier mouse events and needs a real-terminal check

Related to CL-7346

Markdown prose stays terminal-owned: its renderers expose no text-leaf API to highlight or hit-test.
@linear-code

linear-code Bot commented Sep 13, 2026

Copy link
Copy Markdown

CL-7346

A retext that dropped the last URL left the old hit ranges armed, so Ctrl+clicking the old columns still opened. The armer now clears its handlers when no line holds a URL.
@TheGreatAxios

Copy link
Copy Markdown
Collaborator Author

Audit: NEEDS-WORK (security — Windows opener command injection)

Finding (blocking): defaultUrlOpener (src/tui/url-links.ts) routes Windows opens through ["cmd", "/c", "start", "", url]. Bun.spawn with an argv array does not invoke a shell itself, but cmd.exe /c re-parses the assembled command line, so &, | and && inside a transcript URL act as command separators. Transcript URLs are attacker-influenceable (tool output, fetched pages, pasted logs), so Ctrl+clicking a crafted URL on Windows would execute arbitrary commands. Fix: never route through cmd /c — spawn rundll32 url.dll,FileProtocolHandler <url> as argv with no shell. I will push this fix to this branch.

Checked and kept (no change requested):

  • Scheme gate parses (new URL(url).protocol) rather than prefix-matching, so javascript: / file: / mailto: never open.
  • argv-spawn with no shell on the darwin/linux paths.
  • Press/release URL equality: a press that releases anywhere else stays a selection gesture.
  • Stale-handler disarm on retext, uppercase-scheme matching, button-0-only (right-click safe) gating.

Suggestion (non-blocking): a hover URL preview (status line or tooltip showing the target) would mitigate display-text-vs-target phishing; consider as a follow-up.

Verification note: the unit/headless suites pin the gating with a mocked opener, but a real-terminal pass is still needed to confirm the terminal delivers the held modifier on motion/press events and that the spawn resolves into a browser. Not run in this pass (no real-terminal mouse tests here).

cmd.exe re-parses the assembled command line, so &, | and && in an attacker-influenceable transcript URL would execute as command separators. Route win32 through rundll32 url.dll,FileProtocolHandler with the URL as a plain argv element instead; no shell is involved on any platform.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant