Phasing out forwarding of locale settings

Ingo Schwarze schwarze at usta.de
Fri Sep 3 21:49:57 AEST 2021


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


More information about the openssh-unix-dev mailing list