Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Hyperlinks in Terminal Emulators

This isn't made explicit, and I didn't see any concrete consensus in the discussions, how are arbitrary/non-standard URL schemes handled? From the looks of things, it's not the terminal's responsibility, they will just pass the URL to the OS's own file open routines. So if I wanted to generate a link to say, an IRC chatroom:

echo -e '\e]8;;irc://\a#lobby channel\e]8;;\a'

All I will need to do is make sure my IRC client is registered in the system to handle irc:// links. Is that correct?


egmontkob commented Apr 25, 2017

@evaryont You're right, we don't intend to go into such details. It's up to the terminal emulator to decide which schemes it supports and what action it takes on them, probably delegating this decision to some lower level OS routine.

Most terminal emulators already autodetect standard URLs appearing on the screen. On one hand, it's reasonable for them to take the same action, regardless whether e.g. "irc://..." is autodetected as a visible string, or specified explicitly via this new escape sequence. On the other hand, the new one is potentially more easily configurable by the users since they won't have to handcraft complicated regexes, so perhaps some terminal emulators will add a configuration option for this.

It might also make sense for terminal emulators to offer the possibility to override the OS-wide action because the OS-wide registry would probably prefer to open a graphical app, whereas if coming from a terminal emulator, you might want to prefer to open a terminal-based IRC client in a new window/tab of the same terminal emulator, or similarly, prefer a lynx-style browser for http/https rather than a graphical one.

This is an open ended question, leaving room for terminal emulators to come up with nice ideas.

ssbarnea commented Jun 21, 2017

This is really cool! I found this after looking for the same thing myself (and wasting some time with the reddit thread).
Is there any ANSI "coloring" python library already implementing this? I would love to start giving hyperlinks as output. The option to display them raw is not ok.

Foxboron commented Jul 8, 2017

Wouldn't this allow rather ugly attack vectors where the user doesn't understand what he/she is clicking?


egmontkob commented Jul 12, 2017

@ssbarnea Not that I'm aware of. Thanks for spreading the news of this feature and asking others to add support!


egmontkob commented Jul 12, 2017

@Foxboron I'm fairly sure there's no risk here at all. The situation shouldn't be any worse than clicking on a link on an untrusted webpage. In fact, webpages are worse. First, they can leak data via the Referer field which isn't filled out if you click from the terminal emulator. Second, they can do nasty JS tricks to alter the target just when you click on the link (sometimes this is actually used for good purposes, like to inject a redirector which hides the referring page). In the terminal emulator a malicious app can still probably overwrite the link target at any time, but it has no clue when you're about to click.

Any webpage that does harmful things (e.g. delete data stored on a server) by just visiting a link suffer from CSRF bug anyway which can be exploited from browsers (malicious websites) too.

What happens to "data:" urls or pure local (#) links? Any chance to get anything to STDIN or back to a terminal based app that doesn't involve registering a link handler with the window manager? Use case: local link handling inside a "pure" command-line app with hyperlink support.


egmontkob commented Sep 3, 2017

@stefanhaustein Interpretation of different schemes (or lack thereof) is up to the terminal emulator. E.g. with "data:" URLs they might show a popup with the content, or store in a temporary file and open that. Note that with the current limit of 2083 bytes for the URL in both VTE and iTerm2, the "data:" scheme isn't quite useful. I wouldn't want to significantly increase the limit (let alone remove it altogether) because then a malicious utility could cause the terminal emulator to eat tons of memory.

Handling the link inside the existing terminal emulator is alas again something that would be truly problematic. It would raise tons of questions like what to do if an app is already running or if you're ssh'd to a remote host, and probably a whole lot more. Not to mention that if we did anything like this, that would probably introduce serious security concerns.

The closest you can do with the current design is to specify a handler that opens a new terminal window and a specific app inside that, e.g. "lynx" for "http(s)" scheme. I'm not sure if iTerm2 allows you to configure this. GNOME Terminal takes the handler app from the global GNOME-wide configuration, hence it cannot differ from what's used for graphical apps. This is something we might improve on if there's a high demand – or other VTE-based apps might implement this.

@egmontkob: Malicious "utilities" aren't worth worrying about. If you're executing a malicious binary, you've got much bigger problems than a terminal emulator eating up memory. However, catting a text file could be a problem, as people expect text files to be safe to display. This is actually similar to an issue MS-DOS had with the ANSI.SYS driver, only that was much worse, as that allowed random text files to change what the keys on your keyboard do—for instance, making a common letter instead type a command that formats your hard drive and press Enter.


egmontkob commented Sep 13, 2017

@flarn2006 Thanks for the clarification, I indeed did not clearly distinguish these two. A malicious binary can also be a compromised binary on a remote system that you ssh into, in which case it's like locally cating a maliciously constructed text file (plus all the damage being done over there on the compromised system). As far as the terminal emulator is concerned, it's only the incoming byte stream that matters.

hdon commented Oct 10, 2017

A note to any maintainers of terminal emulators out there: please include a prominent option to scale back this feature. I've been using terminal emulators for 20 years and one behavior I find really annoying is clicking even what is obviously a URL and then having it come up in my browser. Sometimes I'm just trying to select text...

(Oh, and rectangle select is a nice feature, too, guys!)

mofux commented Nov 28, 2017

For reference, xterm.js is tracking this feature request here: xtermjs/xterm.js#1134


egmontkob commented Nov 28, 2017

@mofux Thanks, added.

devkev commented Nov 30, 2017

To follow up on @Foxboron's earlier comment, it would be great if this document included a requirement for terminals to prominently inform the user of the actual URL before they click on it, eg. on hover (similar to web browsers). iTerm2 does this, but I'm not sure about other terminals.

This isn't just a convenience, it's important to prevent attacks like '\e]8;;\a\e]8;;\a' (ie. the user thinks they're clicking a link to, but they're actually going to, which is why I think it should be mandatory.

Given that our Matterhorn project was linked to up above, I figure I should note here that our newest Matterhorn release—version 40400.0.0—produces hyperlink escape sequences for all links which appear in the chat. (Matterhorn is built on top of the vty and brick libraries, which are medium- and high-level abstractions over terminals, respectively, and both of these libraries added support for hyperlink escape sequences in October.)


egmontkob commented Dec 1, 2017

@aisamanra: Thanks, added.


egmontkob commented Dec 1, 2017

@devkev: gnome-terminal shows the target as a tooltip (appears about half a second after you stop moving the mouse). Not sure about tilix and I cannot test it right now.

I'm not sure I fully share your concerns. It's a quite complex scenario and I'm wondering if the terminal emulator is the right way to address this, I'm honestly not sure.

Certain utilities use this feature for linkifying what they autodetect as links anyways, just to keep it working across linebreaks or so. As far as I understand, the aforementioned Matterhorn is such an example: it cannot be tricked by a remote user to show URLs where the actual target differs from the visible text. Other utilities, like ls also always produce trustable output.

Another use case is where the visible URL and the target are significantly different. Let's say a site literally called looks totally like Facebook, phishing for your data hoping that you'd enter your credentials there. In this case this malicious URL will also be visible in your browser's URL bar, and I'm not entirely sure how much the terminal emulator also showing this URL would help you notice what's going on.

Yet another use case is where the actual URL looks damn similar to the one it's phishing, let's say (with three o's) or some Unicode ideographs. In this case again the terminal emulator showing the target probably wouldn't help you too much in catching the phishing attempt. Also note that this does not only hold for such OSC 8 explicit hyperlinks, the current feature of autodetecting URLs in pretty much every graphical terminal emulator also suffers from this issue, it isn't addressed there and I'm not aware of anyone ever having complained about it.

To tell a malicious site, it's probably a better approach to have some centrally maintained database of known such sites, and check the URL against that. And that's what modern browsers do when you open the URL. The same functionality could be repeated elsewhere too: In utilities that present links to the users (let's say, terminal based e-mail clients); in the URL-opening framework of popular graphical desktops (e.g. whatever happens behind the scenes after a gtk_show_uri()); or indeed in terminal emulators. I'm not sure what the best place for this is.

Given what browsers already do, terminal emulators here could be another line of defense, but would definitely not be the only one, nor the strongest one. As such, I wouldn't make it a requirement. I'd say terminal emulators are recommended to show the target URL, but it's also up to the users to choose an emulator accordingly (or file feature requests, PRs) if this feature is important for them. Obviously there's also room for further improvements, e.g. some terminal emulators might want download some malware list and check the URL against it, or might highlight the domain name (as browsers do in the URL bar) or might want to warn the user in case non-ASCII letters are present in the domain name, etc.

So I'd suggest that we bring these issues to the attention of terminal emulator developers, and recommend them to at least somehow conveniently let users figure out the URL before they activate it. Does this sound reasonable to you?

I'll also note that soon Vty will not do hyperlinking by default because of garbage output with older versions of VTE. An API call will be required to opt in and enable it. For more info: jtdaugherty/vty#137

devkev commented Dec 4, 2017

@egmontkob, I think you may have missed the point. This isn't about trying to detect malicious sites, or spoofing attempts. It's about users being able to make an informed choice (about clicking on a link). Without the ability to discover the actual url, arbitrary-text links introduce an ambiguity that prevents users from being able to trust any links presented to them. This makes the linking feature effectively useless, and a security risk.

Suppose you have a terminal which:

  • auto links urls
  • displays arbitrary-text links to urls (ie. this spec)
  • does not have any way for users to discover the actual url of these links

Now you (the user) see the linkified text somewhere on your screen. If you click on this, will the Google homepage be loaded in your browser? You have absolutely no way of knowing. Clicking the link could open literally any url at all, including urls that you (the user) would never have chosen to click if you had been properly informed.

This is why it's vital for users to be able to discover the actual url of any link. It's the same reason that web browsers and email clients show users the actual url. It applies to any software that presents arbitrary text hyperlinks.

devkev commented Dec 4, 2017

Also, terminology's ticket tracking this feature is


egmontkob commented Dec 4, 2017

@devkev I understand your usability concerns here, but I don't understand how it's a security or privacy concern, and as such, I'd leave it up to authors of terminal emulators, and leave it up to users to choose a terminal emulator meeting their needs.

As I've already mentioned in this comment, this problem is also present and is more serious on webpages. E.g. search for something in Google and hover over the results. In the bottom corner of the browser, you'll see that the link points let's say to Wikipedia. The moment you click on it (before the browser begins to follow it) the link target is changed to some Google-owned redirector. This is a proof that it can be done on webpages, and hence probably can be done for malicious purposes as well. At least in terminal emulators, the target cannot be altered just when you click on it.


egmontkob commented Dec 4, 2017

@devkev I've added the terminology link, thanks. (Honestly, I don't expect any terminal emulator that refused true color support to implement this one, and hence I myself didn't bother filing feature requests against them.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment