From: "mame (Yusuke Endoh)" Date: 2021-12-09T15:37:43+00:00 Subject: [ruby-core:106600] [Ruby master Feature#18367] Stop the interpreter from escaping error messages Issue #18367 has been updated by mame (Yusuke Endoh). I read [the article about the vulnerability](https://marc.info/?l=bugtraq&m=104612710031920&w=2) again. It clearly insists that this vulnerability should be addressed in the side of terminal emulators. > The responsibility > should rest on the actual terminal emulator; any features that allow file or command-line > access should be disabled by default and more attention should be paid to new features > that implement any use of escape sequences. I did a quick survey of the current status of the two specific issues mentioned in the article. ### "Screen Dumping" issue Now rxvt requires "insecure mode" to enable the feature in question. https://github.com/cpjreynolds/urxvt/blob/master/doc/rxvt.1.pod > insecure: boolean > Enables "insecure" mode. Rxvt-unicode offers some escape sequences that echo arbitrary strings like the icon name or the locale. This could be abused if somebody gets 8-bit-clean access to your display, whether through a mail client displaying mail bodies unfiltered or through write(1) or any other means. Therefore, these sequences are disabled by default. (Note that many other terminals, including xterm, have these sequences enabled by default, which doesn't make it safer, though). > > You can enable them by setting this boolean resource or specifying -insecure as an option. At the moment, this enables display-answer, locale, findfont, icon label and window title requests. I checked the behavior with rxvt-unicode (urxvt) v9.22. With regard to Eterm, the feature in question seems to be disabled by `#if 0` in 2002: https://github.com/mej/Eterm/commit/c9ef7c900204b8e1ca980e02790d6bb45d4aa784 > Mon Apr 29 10:48:33 2002 Michael Jennings (mej) > Disable the screen dump escape sequence and implement a save_buff() > script function instead. ### "Window Title Reporting" issue Now XTerm requires "allowWindowOps" configuration to enable the feature in question. VTE (gnome-terminal) is aware of the issue and [implements the feature as dummy (reports an empty dummy title)](https://github.com/GNOME/vte/blob/db3c6253d7fa1645996a2abd9fd55df414ca4c2d/src/vteseq.cc#L9219-L9225). ``` case VTE_XTERM_WM_GET_WINDOW_TITLE: /* Report a static window title, since the real * window title should NEVER be reported, as it * creates a security vulnerability. See * http://marc.info/?l=bugtraq&m=104612710031920&w=2 * and CVE-2003-0070. */ ``` I also checked Windows Terminal and iterm2. I couldn't find documentation about the feature, but as far as I tested, both do not report window title by the escape sequence in question. ### Conclusion In modern times, I think a consensus has already been reached that this kind of security problems should be solved on the terminal emulator side. If anyone finds a modern terminal emulator still vulnerable, tell me (or the author of the terminal emulator :-). ---------------------------------------- Feature #18367: Stop the interpreter from escaping error messages https://bugs.ruby-lang.org/issues/18367#change-95267 * Author: mame (Yusuke Endoh) * Status: Open * Priority: Normal ---------------------------------------- ## Proposal At the present time, the Ruby interpreter escapes some characters (*1) in error messages when an uncaught error is printed. I'd like to propose stopping this escaping behavior. ``` class MyError < StandardError def message "foo\\bar" end end raise MyError #=> current: test.rb:7: in `
': foo\\bar (MyError) #=> excepted: test.rb:7: in `
': foo\bar (MyError) ``` *1: Escaped characters are any control characters except `\t` and `\n`, and a backslash `\\`. ## Motivation This behavior prevents us from adding an attribution (color, underline, etc.) to the error message because it escapes escape sequences. Nowadays, such a rich presentation of terminal output is more and more important. ``` $ ruby -e 'raise "\e[31mRed\x1b[0m error"' -e:1:in `
': \e[31mRed\x1b[0m error (RuntimeError) ``` Also, the behavior in question leads to rather confusing error printing. See the error output of `"\\".no_method`: ``` $ ruby -e '"\\".no_method' -e:1:in `
': undefined method `no_method' for "\\\\":String (NoMethodError) "\\\\".no_method ^^^^^^^^^^ ``` The two occurrences of `"\\\\"` must be `"\\"`. Worse, the output of error_highlight `^^^^` points wrong position. Note that this issue is never specific to error_highlight. The receiver of NoMethodError, `"\\\\":String`, is also wrongly escaped. It must be `"\\":String`. ## Why the escaping behavior was introduced AFAIK, the behavior was introduced because of a security concern. It is considered harmful for an attacker to be able to print arbitrary escape sequences to victim's terminal. (See [this article](https://marc.info/?l=bugtraq&m=104612710031920&w=2) in detail.) However, I believe it is rare to see the error logs of an application that may be exposed to attacks (i.e. in production mode) in a terminal, as the error output of the Ruby interpreter. Even if that is the case, I think such escaping should be done as a responsibility of the application, and not implicitly by the interpreter. I briefly surveyed other major languages than Ruby, and I could find no language that escapes error messages. This is the transcript of Python and Node.js. ``` $ python3 -c 'raise Exception("\x1b[31mRed\x1b[0m error")' Traceback (most recent call last): File "", line 1, in Exception: Red error $ node -e 'throw("\x1b[31mRed\x1b[0m error")' [eval]:1 throw("\x1b[31mRed\x1b[0m error") ^ Red error (Use `node --trace-uncaught ...` to show where the exception was thrown) ``` Just in case, I reported these behaviors to the security contacts of Python and Node.js, and both responded to me that this is not a securty issue. I think their decisions are quite reasonable. ## Migration It would be a good idea to first make the following behavior as a migration path. * When an error message does not include a control character, no escaping is applied. * When an error message does include a control character, "Warning: this error message is currently escaped because it includes a control character(s), but this will not be escaped in Ruby 3.X" is printed, and the escaping is applied. -- https://bugs.ruby-lang.org/ Unsubscribe: