ssh/tailssh: filter accepted environment variables

Noted by @danderson

Updates #3802

Change-Id: Iac70717ed57f11726209ac1ea93ddc6696605f94
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2022-04-21 14:40:32 -07:00 committed by Brad Fitzpatrick
parent 89832c1a95
commit 8ac4d52b59
2 changed files with 35 additions and 1 deletions

View File

@ -220,7 +220,11 @@ func (ss *sshSession) launchProcess() error {
cmd := ss.cmd
cmd.Dir = ss.conn.localUser.HomeDir
cmd.Env = append(cmd.Env, envForUser(ss.conn.localUser)...)
cmd.Env = append(cmd.Env, ss.Environ()...)
for _, kv := range ss.Environ() {
if acceptEnvPair(kv) {
cmd.Env = append(cmd.Env, kv)
}
}
ci := ss.conn.info
cmd.Env = append(cmd.Env,
@ -493,3 +497,14 @@ func updateStringInSlice(ss []string, a, b string) {
}
}
}
// acceptEnvPair reports whether the environment variable key=value pair
// should be accepted from the client. It uses the same default as OpenSSH
// AcceptEnv.
func acceptEnvPair(kv string) bool {
k, _, ok := strings.Cut(kv, "=")
if !ok {
return false
}
return k == "TERM" || k == "LANG" || strings.HasPrefix(k, "LC_")
}

View File

@ -431,3 +431,22 @@ func TestExpandPublicKeyURL(t *testing.T) {
t.Errorf("on empty: got %q; want %q", got, want)
}
}
func TestAcceptEnvPair(t *testing.T) {
tests := []struct {
in string
want bool
}{
{"TERM=x", true},
{"term=x", false},
{"TERM", false},
{"LC_FOO=x", true},
{"LD_PRELOAD=naah", false},
{"TERM=screen-256color", true},
}
for _, tt := range tests {
if got := acceptEnvPair(tt.in); got != tt.want {
t.Errorf("for %q, got %v; want %v", tt.in, got, tt.want)
}
}
}