Mailing List Archive

Phasing out forwarding of locale settings
Most distributions send locale environment variables by default:

SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
SendEnv XMODIFIERS

And accept them on the server side:

AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS

(Some distributions also use LC_* wildcards.)

Now that servers often use minimal installations which only support a
small set of locales (C, C.UTF-8), would it make sense to discontinue
this practice?

Thanks,
Florian

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Phasing out forwarding of locale settings [ In reply to ]
Hi Florian,

Florian Weimer wrote on Fri, Sep 03, 2021 at 11:55:54AM +0200:

> Most distributions send locale environment variables by default:
>
> SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
> SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
> SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
> SendEnv XMODIFIERS
>
> And accept them on the server side:
>
> AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
> AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
> AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
> AcceptEnv XMODIFIERS
>
> (Some distributions also use LC_* wildcards.)
>
> Now that servers often use minimal installations which only support a
> small set of locales (C, C.UTF-8), would it make sense to discontinue
> this practice?

I think the question is moot. Fiddling with this is at best lipstick
on a pig. There is only one way to make remote shells safe, and
it is not specific to SSH. It requires that *both* of the following
necessary conditions be observed:

1. Make sure your xterm(1) is set to UTF-8 mode. Yes, using UTF-8
mode is critical even when you want to actually use US-ASCII only.
Traditional 8-bit mode cannot be made safe with any locale.

2. Make sure that on each side, either the POSIX locale or an UTF-8
locale is in use; it is not necessary that they match. Using any
other locale on either side is not safe.

See https://undeadly.org/cgi?action=article&sid=20160308204011
for details.

The situation with terminal emulators other than xterm(1) might be
even worse, but i suspect it is unlikely to be better.

Yours,
Ingo
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Phasing out forwarding of locale settings [ In reply to ]
* Ingo Schwarze:

> Hi Florian,
>
> Florian Weimer wrote on Fri, Sep 03, 2021 at 11:55:54AM +0200:
>
>> Most distributions send locale environment variables by default:
>>
>> SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
>> SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
>> SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
>> SendEnv XMODIFIERS
>>
>> And accept them on the server side:
>>
>> AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
>> AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
>> AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
>> AcceptEnv XMODIFIERS
>>
>> (Some distributions also use LC_* wildcards.)
>>
>> Now that servers often use minimal installations which only support a
>> small set of locales (C, C.UTF-8), would it make sense to discontinue
>> this practice?
>
> I think the question is moot. Fiddling with this is at best lipstick
> on a pig. There is only one way to make remote shells safe, and
> it is not specific to SSH. It requires that *both* of the following
> necessary conditions be observed:
>
> 1. Make sure your xterm(1) is set to UTF-8 mode. Yes, using UTF-8
> mode is critical even when you want to actually use US-ASCII only.
> Traditional 8-bit mode cannot be made safe with any locale.
>
> 2. Make sure that on each side, either the POSIX locale or an UTF-8
> locale is in use; it is not necessary that they match. Using any
> other locale on either side is not safe.

We increasingly see a situation where the terminal has some UTF-8 locale
(usually en_US.UTF-8), but the remote end does not recognize that and
falls back to the POSIX locale, often quite noisily.

This configuration matches your safety criteria, but the user experience
is still poor.

Thanks,
Florian

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Phasing out forwarding of locale settings [ In reply to ]
Hi Florian,

Florian Weimer wrote on Fri, Sep 03, 2021 at 12:56:17PM +0200:
> Ingo Schwarze wrote:
>> Florian Weimer wrote on Fri, Sep 03, 2021 at 11:55:54AM +0200:

>>> Most distributions send locale environment variables by default:
>>>
>>> SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
>>> SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
>>> SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
>>> SendEnv XMODIFIERS
>>>
>>> And accept them on the server side:
>>>
>>> AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
>>> AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
>>> AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
>>> AcceptEnv XMODIFIERS
>>>
>>> (Some distributions also use LC_* wildcards.)
>>>
>>> Now that servers often use minimal installations which only support a
>>> small set of locales (C, C.UTF-8), would it make sense to discontinue
>>> this practice?

>> I think the question is moot. Fiddling with this is at best lipstick
>> on a pig. There is only one way to make remote shells safe, and
>> it is not specific to SSH. It requires that *both* of the following
>> necessary conditions be observed:
>>
>> 1. Make sure your xterm(1) is set to UTF-8 mode. Yes, using UTF-8
>> mode is critical even when you want to actually use US-ASCII only.
>> Traditional 8-bit mode cannot be made safe with any locale.
>>
>> 2. Make sure that on each side, either the POSIX locale or an UTF-8
>> locale is in use; it is not necessary that they match. Using any
>> other locale on either side is not safe.

> We increasingly see a situation where the terminal has some UTF-8
> locale (usually en_US.UTF-8),

Note that the locale being UTF-8 isn't sufficient for being safe;
the terminal program must also be set to UTF-8 mode, which is not
the same as having a UTF-8 locale. The locale set in the shell
running inside the terminal (and that's what ssh(1) will look at)
is *totally* irrelevant, and even the locale that was set in the
process that originally fork(2)ed the xterm(1) process does not
necessarily determine the mode that the xterm(1) is using. Some
terminals might even allow the user to change the mode interactively
while the terminal is already running, and doing so will change
*neither* of the two locales mentioned above.

So we are talking about *four* character encoding settings here:

1. locale in the process starting the terminal
2. mode of the terminal process itself (not strictly a "locale")
3. locale in the shell running in the terminal (totally irrelevant)
4. locale in the shell running on the server

Your SendEnv settings are picking up item no. 3, i.e., the one that
is irrelevant.

> but the remote end does not recognize that and
> falls back to the POSIX locale, often quite noisily.
>
> This configuration matches your safety criteria, but the user
> experience is still poor.

Well, the official documentation is quite explicit:

$ man ssh_config
[...]
SendEnv
[...]
The default is not to send any environment variables.

$ man sshd_config
[...]
AcceptEnv
[...]
The default is not to accept any environment variables.

The official example files do not even provide examples how to
change that:

$ cd /usr/src/usr.bin/ssh
$ grep Env ssh_config sshd_config
sshd_config:#PermitUserEnvironment no

You might argue that in a security-sensitive area, changing official
defaults is a poor idea, in particular when it may contribute to
inspiring a false sense of security in users. Either way, neither
passing nor not passing these variables can guarantee safe I/O
handling by the terminal, and i wonder how "poor user experience"
matters as long as the user isn't even protected from remote attacks
against the integrity of terminal I/O.

On operating systems supporting locales other than UTF-8, there is no
real solution making any of this safe. Even unconditionally forcing
the locale to UTF-8 on both sides (in both ssh and sshd) would not be
safe on such systems because the user might have set their terminal
not to UTF-8 mode, but to some other mode, and you can't change the
(likely unsafe) terminal mode from inside the ssh(1) program.

That's why i'm calling this discussion moot. It looks like a nearly
irrelevant detail on top of a much more serious problem to me.

Yours,
Ingo
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Phasing out forwarding of locale settings [ In reply to ]
On Fri, 3 Sep 2021, Florian Weimer wrote:

> We increasingly see a situation where the terminal has some UTF-8 locale
> (usually en_US.UTF-8), but the remote end does not recognize that and
> falls back to the POSIX locale, often quite noisily.

The noise of the fallback is the only problem with that, though.

I tend to have my locale settings in my ~/.mkshrc on either side,
so I get sanitised locale environment parameters anyway. This is
the easiest, and perhaps the most reliable, way to fix this (for
interactive/shell sessions) but outside of the scope of ssh…

bye,
//mirabilos
--
Infrastrukturexperte • tarent solutions GmbH
Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
Telephon +49 228 54881-393 • Fax: +49 228 54881-235
HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

****************************************************
/?\ The UTF-8 Ribbon
? ? Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
? HTML eMail! Also, https://www.tarent.de/newsletter
? ? header encryption!
****************************************************
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Phasing out forwarding of locale settings [ In reply to ]
On 03.09.21 11:55, Florian Weimer wrote:
> Most distributions send locale environment variables by default:
[...]
> And accept them on the server side:
[...]
> Now that servers often use minimal installations which only support a
> small set of locales (C, C.UTF-8), would it make sense to discontinue
> this practice?

In order to achieve what exactly?

I'm no stranger to putting "export LANG=C" into shell scripts so that I
can reliably parse command outputs, but on the other hand, our servers
do document processing and some of the 3rd party software used will
introduce strange misrepresentations unless we have both(!) en_US.UTF-8
and de_DE.UTF-8 installed. Allowing the respective variables to be
carried from client to server automatically keeps users from getting
innovative with ~/.bashrc and the like ...

Regards,
--
Jochen Bern
Systemingenieur

Binect GmbH
Re: Phasing out forwarding of locale settings [ In reply to ]
* Thorsten Glaser:

> On Fri, 3 Sep 2021, Florian Weimer wrote:
>
>> We increasingly see a situation where the terminal has some UTF-8 locale
>> (usually en_US.UTF-8), but the remote end does not recognize that and
>> falls back to the POSIX locale, often quite noisily.
>
> The noise of the fallback is the only problem with that, though.

Some applications also fail.

> I tend to have my locale settings in my ~/.mkshrc on either side,
> so I get sanitised locale environment parameters anyway. This is
> the easiest, and perhaps the most reliable, way to fix this (for
> interactive/shell sessions) but outside of the scope of ssh…

Some of have write permission under /etc, including on new
installations. I had hoped to find some distribution consensus through
this list.

Thanks,
Florian

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Phasing out forwarding of locale settings [ In reply to ]
[resending after subscribing, sorry for the possible duplicate]
03.09.2021 20:02, Jochen.Bern at binect.de (Jochen Bern) ?????:
> On 03.09.21 11:55, Florian Weimer wrote:
>> Most distributions send locale environment variables by default:
> [...]
>> And accept them on the server side:
> [...]
>> Now that servers often use minimal installations which only support a
>> small set of locales (C, C.UTF-8), would it make sense to discontinue
>> this practice?
>
> In order to achieve what exactly?
>
> I'm no stranger to putting "export LANG=C" into shell scripts so that I
> can reliably parse command outputs, but on the other hand, our servers
> do document processing and some of the 3rd party software used will
> introduce strange misrepresentations unless we have both(!) en_US.UTF-8
> and de_DE.UTF-8 installed. Allowing the respective variables to be
> carried from client to server automatically keeps users from getting
> innovative with ~/.bashrc and the like ...

I would rather not forward the locale settings, and especially not
accept them on the server side, and here is why.

More and more newbie Linux/cloud sysadmins use MacOS, not Linux, as
their main system, and we have to deal with it. MacOS, by default, sends
locale-related environment variables. Here is their default
configuration in /etc/ssh/ssh_config, minus comments:

Host *
SendEnv LANG LC_*

So, it will send locale-related environment variables. Here is the
default environment on a Mac running Big Sur:

TMPDIR=/var/folders/sj/81q_d2g14f9_9_q5qp79yp3r0000gn/T/
__CFBundleIdentifier=com.apple.Terminal
XPC_FLAGS=0x0
TERM=xterm-256color
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.ofNlVbvqiZ/Listeners
XPC_SERVICE_NAME=0
TERM_PROGRAM=Apple_Terminal
TERM_PROGRAM_VERSION=440
TERM_SESSION_ID=220850B1-9079-4EC2-BE40-E5A79112F574
SHELL=/bin/zsh
HOME=/Users/user
LOGNAME=user
USER=user
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
SHLVL=1
PWD=/Users/user
OLDPWD=/Users/user
LC_CTYPE=UTF-8
_=/usr/bin/env

On Debian, the server-side configuration (minus comments) is as follows:

ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server

So it accepts locale-related variables. Including this one:

LC_CTYPE=UTF-8

But, this is valid on MacOS only. It is not a valid locale on Linux, and
will never be. So, MacOS users that try to ssh to Debian systems will
see locale errors (e.g. from Perl programs), and they often don't know
why these errors appear and how to fix them. They would be better served
by the Debian server applying its default locale settings. I even had to
add some slides about this problem to my (proprietary and commercial)
Linux sysadmin course, and would love to remove them.

--
Alexander E. Patrakov
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Phasing out forwarding of locale settings [ In reply to ]
On 09.09.21 17:51, Alexander E. Patrakov wrote:
> 03.09.2021 20:02, Jochen.Bern at binect.de (Jochen Bern) ?????:
>> On 03.09.21 11:55, Florian Weimer wrote:
>>> Now that servers often use minimal installations which only support a
>>> small set of locales (C, C.UTF-8), would it make sense to discontinue
>>> this practice?
>>
>> In order to achieve what exactly?
>
> I would rather not forward the locale settings, and especially not
> accept them on the server side, and here is why.
>
> More and more newbie Linux/cloud sysadmins use MacOS, not Linux, as
> their main system, and we have to deal with it. [...] Here is the
> default environment on a Mac running Big Sur:
>
[...]> TERM_PROGRAM=Apple_Terminal
> LC_CTYPE=UTF-8
[...]
>
> On Debian, the server-side configuration (minus comments) is as follows:
>
[...]
> AcceptEnv LANG LC_*
[...]
>
> So it accepts locale-related variables. Including this one:
>
> LC_CTYPE=UTF-8
>
> But, this is valid on MacOS only. It is not a valid locale on Linux, and
> will never be.

Most importantly (IMHO), that setting for a *language* env var fails to
indicate *a language* (or anything else that qualifies as localization).
Is there any locales support in MacOS, GUI excluded, in the first place?

> So, MacOS users that try to ssh to Debian systems will
> see locale errors (e.g. from Perl programs), and they often don't know
> why these errors appear and how to fix them.

My guess would be that we'll see Linux distribs do the equivalent of "ln
-s /usr/lib/locale/C.utf8 /usr/lib/locale/UTF-8" Any Day Now™ if MacOS
continues to throw that value around ...

One important point is that OpenSSH, as a trans-distrib upstream,
apparently *already does what you're asking*; the sshd_config manpage
says that "The default is not to accept any environment variables", even
on my CentOS systems, which come with

> # Accept locale-related environment variables
> AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
> AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
> AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
> AcceptEnv XMODIFIERS

as *the distrib's* default config file content, and there is *no*
AcceptEnv to be seen in

https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/sshd_config?rev=1.104&content-type=text/x-cvsweb-markup

, not even commented out.

So, the ones you actually have to convince are the maintainers of
various distribs' OpenSSH packages. Who *might* have more interest in
that TheirOwnDistrib-to-TheirOwnDistrib logins work as usual,
*including* carrying the localizations along that work fine *there* ...

What you could ask for *here* is that OpenSSH stops supporting SendEnv /
AcceptEnv altogether - but I have a hunch that you'll need a much more
convincing case to get *that* thermonuclear solution.

Regards,
--
Jochen Bern
Systemingenieur

Binect GmbH
Re: Phasing out forwarding of locale settings [ In reply to ]
Hi Jochen,

Jochen Bern wrote on Thu, Sep 09, 2021 at 08:28:27PM +0200:

> What you could ask for *here* is that OpenSSH stops supporting SendEnv /
> AcceptEnv altogether - but I have a hunch that you'll need a much more
> convincing case to get *that* thermonuclear solution.

I realize you may not be serious about this - but just in case
someone thinks you are: that is hardly a solution, and much less a
"thermonuclear" one, because some operating systems and operating
system distributions have been known at various times in the past
for patching features back in after said features had been removed
from upstream software for security reasons.

Besides, passing environment variables may occasionally be a useful
feature in unusual situations for very experienced users who know
what they are doing, especially in configuration stanzas where both
the client host and the server host are tightly defined. Needless
to say, passing LC_* is usually *not* useful because defining it
statically on both sides is usually simpler and more robust. But
*other* variables may be worth passing in special configurations.
Passing variables by default, even for users who may have no idea
what is happening and what the security implications are, and *for
all hosts*, certainly doesn't look like a particularly smart idea
to me personally.

As i said earlier, OpenSSH already makes a pretty strong statement
by not only documenting that this feature is off by default (except
for TERM) but also by not even listing it in the "ssh_config"
and "sshd_config" example configuration files, which list various
other options that users are more likely to need knowing about.

I believe i said this before, but it seems people missed it:
What is discussed here has security implications. Specifically,
if the shell on the server uses a locale that does not match the
mode the client terminal or terminal emulator is using, the client
is susceptible to terminal state corruption attacks that can be
triggered by remote unprivileged users, for example by creating
files with crafted, malicious file names in /tmp/ and hoping the
user logging in remotely will issue a command like "ls /tmp/".
Depending on the client terminal configuration, such attacks can
leverage a wide variety of terminal features - for example, freezing
the client terminal (DOS attack) is often trivial, usually in
multiple different ways, but more elaborate attacks like simulating
or falsifying output or in the worst case, injecting bogus, hostile
keystrokes into the client terminal might sometimes also be possible.

Neither passing nor not passing these variables does anything to
improve security. You are passing *the wrong data*. What matters
is the mode the client terminal is running in. That is not the
same as the locale(1) set in the shell running inside that terminal.
On top of that, as you observed, passing that irrelevant locale to
the server by no means assures that the remote host will accept
it and/or even supports it.

Again, i don't think a technical solution exists. What matters is
educating users (1) what terminal modes are and why they matter
and (2) that using SSH safely requires considering the terminal
mode on the client side, and the locale on the remote side, before
connecting. I very much doubt that trying to invent some kind
of magical setting will help with that - quite apart from the fact
that magic doesn't work in the first place.

Yours,
Ingo
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
RE: Phasing out forwarding of locale settings [ In reply to ]
On September 10, 2021 6:37 AM, Jochen Bern wrote:
>Jochen Bern wrote on Thu, Sep 09, 2021 at 08:28:27PM +0200:
>
>> What you could ask for *here* is that OpenSSH stops supporting SendEnv
>> / AcceptEnv altogether - but I have a hunch that you'll need a much
>> more convincing case to get *that* thermonuclear solution.
>
>I realize you may not be serious about this - but just in case someone thinks you are: that is hardly a solution, and much less a
>"thermonuclear" one, because some operating systems and operating system distributions have been known at various times in the past
>for patching features back in after said features had been removed from upstream software for security reasons.
>
>Besides, passing environment variables may occasionally be a useful feature in unusual situations for very experienced users who
know
>what they are doing, especially in configuration stanzas where both the client host and the server host are tightly defined.
Needless to
>say, passing LC_* is usually *not* useful because defining it statically on both sides is usually simpler and more robust. But
>*other* variables may be worth passing in special configurations.
>Passing variables by default, even for users who may have no idea what is happening and what the security implications are, and
*for all
>hosts*, certainly doesn't look like a particularly smart idea to me personally.

There are some subsystems, like git, which pass critical environment variables to the SSH server environment that control its
operation. Without those variables, git will be handcuffed. The thermonuclear option is not viable in the long-term. Locale is a
different subject, I think.

-Randall

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Phasing out forwarding of locale settings [ In reply to ]
On 10.09.21 12:36, Ingo Schwarze wrote:
> Jochen Bern wrote on Thu, Sep 09, 2021 at 08:28:27PM +0200:
>> What you could ask for *here* is that OpenSSH stops supporting SendEnv /
>> AcceptEnv altogether - but I have a hunch that you'll need a much more
>> convincing case to get *that* thermonuclear solution.
>
> I realize you may not be serious about this

Well, *half*-joking, actually. When passing on a user's locale is seen
primarily as a potential attack vector, worse than forcing every which
user to try to master the CLI in the one language chosen by the admin,
then I don't quite see what setting *would* be considered safe enough
for forwarding. *Especially* not $TERM with all its historic baggage, I
guess.

> that is hardly a solution, and much less a
> "thermonuclear" one, because some operating systems and operating
> system distributions have been known at various times in the past
> for patching features back in after said features had been removed
> from upstream software for security reasons.

I referred to the differences between upstream (and OpenBSD-oriented)
OpenSSH and the distribs' OpenSSH packages myself as well, so yes. It
would likely serve to make *some* distribs incompatible to SendEnv,
though, and from there, "broken window theory" *might* take hold. It'd
have a better chance of triggering the global swing than the upstream
"leading by example" of not AcceptEnv'ing locale settings (which they
already do, pretty much unnoticed, if the current requests are any
indication).

(Note that I'm *not* in favor of stunting env var forwarding, but that
doesn't keep me from pondering how it *could* be done, and how
apparently not.)

> Needless
> to say, passing LC_* is usually *not* useful because defining it
> statically on both sides is usually simpler and more robust.

I have experienced the communication between a German NOC/ops and a
French dev team in an enterprise that had a "just have everyone speak
English" policy. If we hadn't all been IT professionals with years of
experience in pre-locales computers, and using the same prod platform
CLIs consequently would have been as much of a stutterfest as the phone
calls were ...

> I believe i said this before, but it seems people missed it:
> What is discussed here has security implications. Specifically,
> if the shell on the server uses a locale that does not match the
> mode the client terminal or terminal emulator is using, the client
> is susceptible to terminal state corruption attacks

While forcing the server to make (fixed global) choices *without* having
any information on the client software's status and the user's native
language will avoid any mismatch ... seriously?

> Neither passing nor not passing these variables does anything to
> improve security. You are passing *the wrong data*. What matters
> is the mode the client terminal is running in.

I consider it *very* vital that the login on some remote machine doesn't
suddenly talk to me in Turkish just because the guy who installed the OS
liked that better; it's a DoS attack on me as much as falsifying
filenames in the "ls" output is.

(And yes, my current employer had a *number* of IT guys of Turkish
origin in its early days, so that's not a completely outlandish scenario.)

But tell me this: If it is so important that the terminal mode be
communicated correctly, why doesn't any terminal software I know at
least reflect the *current* mode into $TERM, which already *is* both
earmarked for the purpose of passing information about the terminal, and
special-cased by OpenSSH?

Regards,
--
Jochen Bern
Systemingenieur

Binect GmbH
Re: Phasing out forwarding of locale settings [ In reply to ]
Hi Jochen,

Jochen Bern wrote on Fri, Sep 10, 2021 at 11:24:56PM +0200:
> On 10.09.21 12:36, Ingo Schwarze wrote:
>> Jochen Bern wrote on Thu, Sep 09, 2021 at 08:28:27PM +0200:

>>> What you could ask for *here* is that OpenSSH stops supporting SendEnv /
>>> AcceptEnv altogether - but I have a hunch that you'll need a much more
>>> convincing case to get *that* thermonuclear solution.

>> I realize you may not be serious about this

> Well, *half*-joking, actually. When passing on a user's locale is seen
> primarily as a potential attack vector,

That is not what i was trying to say. Quite to the contrary, i
said "Neither passing nor not passing these variables does anything
to improve security." What surprises me is that people discuss
passing irrelevant data while at the same time apparently ignoring
the actual problem.

> worse than forcing every which user to try to master the CLI in the
> one language chosen by the admin,

That is definitely not required, in no case whatsoever.

When you first log into a machine, for security reasons, you have
to check *anyway* what the default locale(1) settings are (even
though i do not doubt many users neglect doing that). If these
locale(1) settings are unsafe with the terminal mode you are using
on any of the machines you will be connecting from, then you have
to define the necessary LC_* variables in the adequate shell startup
files in your home directory on the target machine, such that they
are safe with all terminal modes you will use on machines you are
connecting from. From that point onward, whatever locale(1) defaults
the sysop on the target machine may have chosen no longer apply to you.

When connecting from a new machine, you need to check your terminal
mode before connecting and consider whether it is safe with the
locale(1) settings you chose earlier on the target machine, and
change the terminal mode if it is not safe, before you connect. In
the relatively unusual case that this is not possible, if you trust
the sysop of the target machine enough to not put malicious code
into global shell startup files, you can connect even with an unsafe
terminal mode, but then the first thing you do on the target machine
after connecting is of course adjusting the remote locale(1) manually
for this unusual connection before you start any real work on the
remote machine.

Obviously, none of this can be automated, because it depends on various
factors that none of the involved programs and machines can inspect,
in particular:
* Which terminals or terminal emulators and which modes you use
on *all* the machines you may be connecting from (the target
machine can know nothing about that, and even the shell you
are starting the ssh(1) client from cannot really know that
reliably).
* Which locales are available on the target machine (none of the
machines you are connecting from can know that).

> then I don't quite see what setting *would* be considered safe
> enough for forwarding.

Again, SendEnv / AcceptEnv cannot *make* any of this safe.
Users need to use their brains to make their connections safe.

And *if* users use SendEnv / AcceptEnv - typically for reasons other
than safety - then again, they have to use their brains to make
sure what they do afterwards is safe with the SendEnv / AcceptEnv
settings they chose earlier.

> *Especially* not $TERM with all its historic baggage, I guess.

At least $TERM is usually set by the terminal emulator, so it usually
matches the terminal you are really using on the client side.
Besides, the ssh_config(5) manual explains that passing it is
required by the protocol, and it is indeed not clear to me how
a pseudo terminal on the server should behave without it.

[...]
>> Needless
>> to say, passing LC_* is usually *not* useful because defining it
>> statically on both sides is usually simpler and more robust.

> I have experienced the communication between a German NOC/ops and a
> French dev team in an enterprise that had a "just have everyone speak
> English" policy. If we hadn't all been IT professionals with years of
> experience in pre-locales computers, and using the same prod platform
> CLIs consequently would have been as much of a stutterfest as the phone
> calls were ...

I don't really see the problem here. In that company, you would
obviously set all computers to a default of LC_ALL=en_US.UTF-8
(or en_GB.UTF-8 if that is what you prefer for some reason) and
tell all employees to make sure all their terminals run in UTF-8
mode all the time, on all company and private computers they use
for connecting to company equipment. Problem completely solved
without passing any environment variables around.

If any individual employee desires to ignore company policy, they
can still set LC_ALL=de_DE.UTF-8 or even LC_ALL=ja_JA.UTF-8 to their
heart's content in their personal shell initialization files on all
company and private computers where they want that, and they are
still safe as long as they stick to the *.UTF-8 part.

>> I believe i said this before, but it seems people missed it:
>> What is discussed here has security implications. Specifically,
>> if the shell on the server uses a locale that does not match the
>> mode the client terminal or terminal emulator is using, the client
>> is susceptible to terminal state corruption attacks

> While forcing the server to make (fixed global) choices *without* having
> any information on the client software's status and the user's native
> language will avoid any mismatch ... seriously?

No, it will not, and i didn't intend to claim that.

What matters is how people behave, not whether these variables are
passed around or not.

>> Neither passing nor not passing these variables does anything to
>> improve security. You are passing *the wrong data*. What matters
>> is the mode the client terminal is running in.

> I consider it *very* vital that the login on some remote machine doesn't
> suddenly talk to me in Turkish just because the guy who installed the OS
> liked that better; it's a DoS attack on me as much as falsifying
> filenames in the "ls" output is.

When first logging into a new machine, you have to check the locale(1)
settings anyway. You have to do that even if you use SendEnv -
because you don't know beforehand whether that new machine will
AcceptEnv, and even if it does, whether it has the locale that you
send to it installed. Also remember that locale names are not
standardized, so your preferred locale might be installed, but using
a different name.

> (And yes, my current employer had a *number* of IT guys of Turkish
> origin in its early days, so that's not a completely outlandish scenario.)
>
> But tell me this: If it is so important that the terminal mode be
> communicated correctly, why doesn't any terminal software I know at
> least reflect the *current* mode into $TERM, which already *is* both
> earmarked for the purpose of passing information about the terminal, and
> special-cased by OpenSSH?

That is a good question. I cannot really make an authoritative statement
about that because i do not maintain any terminal emulator package.

Then again, let me speculate that designing such a feature might
not be trivial for more than one reason. Firstly, at least some
terminal emulators - including xterm(1) - support changing the mode
interactively, and i am not aware of any way to change environment
variables in child processes that were started earlier. On top of
that, even though there is historical precendent for providing more
than one alternative $TERM setting for the same kind of terminal,
and while it might be possible to communicate some aspects of
terminal settings of some terminal emulator implementations via
$TERM, terminal settings can be numerous, and i'm not sure all that
can reasonably be communicated via $TERM. In particular, the
character set and encoding expected by the terminal matters for
what we are discussing, and i'm not sure that can in general be
communicated through $TERM. At least it would need careful design
to not go overboard.

And even if some terminal emulator would implement something like that,
users would still have to use their brains and check whether all the
terminals they are using actually do that and whether the servers
they connect to actually use the settings being passed correctly,
so i don't think it would fundamentally change the situation that
blindly relying on passing or not passing some environment variables
is insufficient.

Besides, even if the xterm(1) could somehow bypass the local shell
and the ssh(1) client program and communicate to the server that
it is using traditonal 8-bit ISO-Latin-1 mode (which is typical
example of an unsafe mode no matter what the remote locale is),
what is the server supposed to do about that? Setting an ISO-Latin-1
locale on the server wouldn't help much, and on top of that, such
a locale is not even likely to be installed on a server nowadays.

I still think that passing data around that is closely related to an
actual problem, but not really contributing to a solution of that
problem, is not a smart idea. Focussing the discussion on whether
or not irrelvant data should be passed by default does not seem
like the ideal kind of discussion either.

Yours,
Ingo
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Phasing out forwarding of locale settings [ In reply to ]
On Sat, 11 Sep 2021, Ingo Schwarze wrote:

> When you first log into a machine, for security reasons, you have
[…]
> connecting from. From that point onward, whatever locale(1) defaults
> the sysop on the target machine may have chosen no longer apply to you.

Exactly!

> When connecting from a new machine, you need to check your terminal
[…]
> for this unusual connection before you start any real work on the
> remote machine.

Right.

You can make this a little safer by using a terminal in ASCII mode and…

$ ssh -t env LC_ALL=C sh
(or mksh -l or bash --login)

… for that first connection. There can still be attack vectors then,
but in that case/lack of trust, you probably don’t want to connect
at all.

> * Which terminals or terminal emulators and which modes you use

This is really tricky. xterm, for example, has control sequences to
trigger hardcopies and other fun, which aren’t disabled *that* easily.
Moreover, not just ESC but also CSI (\x9B) triggers them.

Running something like GNU screen, tmux, or perhaps even window(1)
(I don’t even think this is available on GNU/Linux but OpenBSD at
least had it at some point), that reduces the capabilities of your
terminal, might make sense in a lack of trust scenario. Heh, isn’t
that a good project idea, make a reduced-functionality terminal-in-
terminal emulator. Perhaps even one that can recode like luit(1).

Hmm, I guess when I ever have the time for that I could add this
to screen whose codebase, horrid though it is, I’m at least somewhat
familiar with…

> * Which locales are available on the target machine (none of the
> machines you are connecting from can know that).

The C locale should be ubiquitous, though, on the other hand, it
only makes the first 128 chars defined; what the upper half is is
up to the system. \x9B, for example, is ¢ in cp437 so it could even
show up in a welcoming message showing the prices to use the machine.

> Again, SendEnv / AcceptEnv cannot *make* any of this safe.
> Users need to use their brains to make their connections safe.

For some reason it’s hard to get that point across ?

But to get back to Florian’s initial question… OpenSSH by default
doesn’t accept or send the locale-related environment variables,
though whether this is because of forethought or simply because
OpenBSD didn’t use them is up to interpretation. So accepting and
sending them is a somewhat cross-distro deviation from the normal
behaviour anyway and “Phasing out forwarding of locale settings”
would just be returning to the upstream default, so it’s probably
not questionable to do. Getting maintainers to actually do it now…

> > *Especially* not $TERM with all its historic baggage, I guess.
>
> At least $TERM is usually set by the terminal emulator, so it usually
> matches the terminal you are really using on the client side.

And it’s not $TERMCAP. That’s the funny one.

> Besides, the ssh_config(5) manual explains that passing it is
> required by the protocol, and it is indeed not clear to me how
> a pseudo terminal on the server should behave without it.

Right. Having used systems from a (real or emulated) serial console,
which (obviously) cannot set $TERM properly at first, this is not fun.

> I don't really see the problem here. In that company, you would
> obviously set all computers to a default of LC_ALL=en_US.UTF-8

I’ve proposed a C.UTF-8 around 2013 which has made its way into first
eglibc then glibc in Debian, and musl, and AFAIHH FreeBSD(?), and
there’s talk of supporting this more broadly (glibc upstream I hope).

On the other hand, on systems where this doesn’t exist, there’s
usually en_US.UTF-8 unless the system doesn’t ship all locales by
default (Debian again) or is HP/UX (which needs en_US.utf8).

But setting one of these as sensible default in the global shell
initialisation file on all servers, allowing users to customise
it in their local ones if needed, and…

> tell all employees to make sure all their terminals run in UTF-8
> mode all the time, on all company and private computers they use

… that, indeed solves this problem.

Another thing you could do, server-side, is to guess the terminal
encoding. This is fragile as hell though. Years ago I’ve come up
with:

• flush all I/O
• output "\030\032\r\xE2\x82\xAC.\033[6n"
• read back the terminal’s response
? 1 is probably EUC-JP, EUC-KR
? 3 is probably UTF-8
? 4 is probably ISO-8859
? 5 is probably Shift-JIS
• output "\r \r" and flush

This is fragile for multiple reasons. It depends on the terminal
actually responding to the column enquiry, not exploding on the
characters sent, etc. and (because it needs to flush, send, then
wait for the response) takes a noticeable amount of time. It’ll
also return the wrong cursor position if the user begins typing
while this is running.

Standardising on UTF-8 terminals is the way to go, in 2021 even
more so than in 2006. Looking at the CVS log I’ve only written
this because Linux’ vt-is-UTF8 utility is Linux-specific.

> can still set LC_ALL=de_DE.UTF-8 or even LC_ALL=ja_JA.UTF-8 to their

(ja_JP, I think)

> > language will avoid any mismatch ... seriously?
>
> No, it will not, and i didn't intend to claim that.
>
> What matters is how people behave, not whether these variables are
> passed around or not.

Right. This suggestion has the greatest potential to avoid mismatches
if users avoid doing some things (like running n?n-UTF-8 terminals)
though.

> send to it installed. Also remember that locale names are not
> standardized, so your preferred locale might be installed, but using

*cough* HP/UX *cough*

Incidentally “locale -a” on a GNU system also shows the “.utf8” variant
but there may be systems that don’t work with *that*, so…

> > least reflect the *current* mode into $TERM, which already *is* both

$TERM is an index into a list of terminals shipped with the server OS.
Adding anything to this is a multi-year process (consider how long it
took for screen to be added) and must be avoided at all cost. (There’s
this Debian package called ncurses-term that ships some extra entries,
so for example GNU screen in xterm has TERM=screen-xterm instead of
just screen, leading to failures with all servers that don’t have this
extra package installed… or simply run a different operating system. I
consider installing this package harmful.) st and tmux are also usually
missing etc.

The termcap/terminfo databases are AFAICT also not concerned about the
encoding, so this isn’t the right place. It would work if, decades ago,
people had done something like “append +anything to a TERM and it’ll
look it up by basename” but they didn’t and we can’t change this now.

bye,
//mirabilos
--
Infrastrukturexperte • tarent solutions GmbH
Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
Telephon +49 228 54881-393 • Fax: +49 228 54881-235
HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

****************************************************
/?\ The UTF-8 Ribbon
? ? Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
? HTML eMail! Also, https://www.tarent.de/newsletter
? ? header encryption!
****************************************************
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev