Déjà vu: Ghostly CVEs in my terminal title
dgl.cx
dgl.cx
I want to say thanks to @dgl for reporting this, and this article is also expertly written.
I also have to say for me personally its quite embarrassing because as I told @dgl when he reported this: I’ve studied his work before and made it a note to test Ghostty against his past discoveries prior to release. And I… quite simply forgot. I didn’t make an issue for myself so it slipped away and here I am with egg on my face. I’m sorry!
But, I appreciate @dgl for the security report, reviewing the fix, and continuing to be an active user of the terminal. I also shared with him some broader thoughts on terminal security in general. Addressing terminal security in a more fundamental way is one of the first proposals I want to make regarding terminal innovation.
My thinking is still too early and under-researched for a formal proposal. But my general feeling having built a terminal over the past 2 years is that the security surrounding escape sequences is fundamentally flawed and poking one by one at these sequences to try to make them individually safe doesn’t feel like the right long term solution.
The surface area is too large and the complexity of some of the newer sequences too high (i.e. Kitty Graphics) to be confident in secure implementations. DoS is far too easy with terminals (Ghostty has a handful of known DoS attacks, but so does pretty much every other terminal I know of). And some legacy sequences are just kind of shocking to have immediately available. For example, DECCOLM is available in macOS Terminal.app. If you issue a DECCOLM (CSI ? 3 h I believe), Terminal.app will physically resize the window and lock it to 132 columns. You can very easily crash Terminal.app at anytime by sending enough of these (a DoS attack). There are many more.
Part of my thinking is trying to design a mechanism that can effectively create something akin to either CPU protection rings or OpenBSD’s pledge() syscall. Whatever the mechanism, the general idea is: reduction of capability.
For example, it makes sense for a shell to be extremely powerful. It’s literally a code execution device. However, it doesn’t make much sense for cat to be able to execute arbitrary escape sequences (which it does today in any terminal). Whether it is the shell or cat itself, something should be able to tell a terminal: “hey, only execute some subset of escape sequences (or none at all).” For cat, that might be none or perhaps just SGR sequences (styles, colors, etc.). The insecurity of cat-ing or tail-ing any form of data that could contain user-generated data is hopefully well known at this point…
As I said before, this thinking is all still very raw and I don’t have anything concrete to proposal. I want to share this because I want folks to know that I’m thinking about it, and perhaps others may be interested in thinking about it with me… if so, please contact me. I’ve already shared this line of thinking with @dgl as well.
This entire class of exploits (query responses with user controlled data leading to shells executing commands) would be removed if shells just moved to using the kitty keyboard protocol with all key events represented as escape codes and implemented a full escape code parser for data received form the terminal. You cannot embed an escape code inside another, or while technically you can, it is trivial to implement a security policy of disallowing these in both terminals and shells. Then barring implementation bugs in the escape code parser (which can easily be shipped as a standalone native code library) you dont have this entire class of issues and the associated one that the bracketed paste hack was created to address.
Also note my thoughts (very much not even close to being a proposal) are very raw. Inviting this kind of discussion is exactly what I hope to do :)
Reduction of capability in general is not intended to address all class of security issue. For example you’d still want unsafe paste detection (to detect newlines or attempted bracketed paste escapes) on a prompt line.
But I think having a mechanism to eliminate the possibility of entire class of actions without wholesale disabling them in the terminal emulator is a desirable property. Right now a lot of these features are mostly on/off.
I can, kind of, see the utility of a pledge() type system within a single program, but in a shell, whose whole job is basically running programs it knows nothing about beyond their name? How would that work?
Id love to continue this discussion, but I think HN threads probably aren’t the right medium. If you’d like I can email you or we can schedule a call. I’m not trying to seek privacy, I’d be happy for any to be recorded or shared publicly, I just don’t find HN to be a good place if you really want to dive into this!
I'll remember his comments as an example of how much pettiness both drives and undermines OSS.
1. The shell could have a keybind (say, ctrl+enter) which runs the command with (for example) only styling enabled (CSI m sequences).
2. You could write a wrapper around any program to do the same. The shell doesn't need to know anything about the system, but instead you have a wrapper that disables and then reenables said sequences.
3. A program itself can opt in by turning on the feature at launch. This allows CLI / TUI developers to "safeguard" their programs from malicious attacks.
Short version: as defined, Mode 16 can deliver many megabytes of CSI parameters before the parser ever sees the `u` telling it what it's parsing. Since this is violently different from any other CSI code ever proposed or implemented, it cannot be parsed using any technique or parser which expects sane behavior.
This isn't the only problem with KKB, it must be deprecated and replaced.
Terminal emulators and TUI applications belong with the DMG Gameboys, Commodore 64's, and DOSBoxes: as a historical curiosity and something for the enthusiasts to enjoy after hours. But we've come to rely on them almost to the point where they're being fetishised; most of us using this technology nowadays aren't even questioning its negative impact.
We need better command line / REPL environments. We need better cross-platform GUI toolkits. We need better remote access. And we need to let go of the TV teletype.
The current effort can at least be pointed towards something.
I'm weirdly attracted to Tk (with Tcl or Tkinter). It's not shiny, but it's very practical.
During prompt injection an attacker can cause such ANSI escape codes to be emitted!
Check out this post to learn more about Terminal DiLLMa and how to mitigate it:
https://embracethered.com/blog/posts/2024/terminal-dillmas-p...
[1] "Kvt bug": <https://seclists.org/bugtraq/1999/Sep/432>
Things like this make me a little more cautious about standard out in general! More research to do.