Skip to content

Commit a987f39

Browse files
committed
allow specifying a whitelist of env vars to pass from client
Change-type: major Signed-off-by: Will Boyce <[email protected]>
1 parent df5bc2e commit a987f39

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

Diff for: balena/main.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"os"
2828
"path"
2929
"runtime"
30+
"strings"
3031
"syscall"
3132

3233
"github.com/balena-io/sshproxy"
@@ -49,7 +50,7 @@ func init() {
4950
pflag.CommandLine.Int64P("shell-gid", "g", -1, "Group to run shell as (default: current gid)")
5051
pflag.CommandLine.StringP("auth-failed-banner", "b", "", "Path to template displayed after failed authentication")
5152
pflag.CommandLine.IntP("max-auth-tries", "m", 0, "Maximum number of authentication attempts per connection (default 0; unlimited)")
52-
pflag.CommandLine.BoolP("allow-env", "E", false, "Pass environment from client to shell (default: false) (warning: security implications)")
53+
pflag.CommandLine.StringP("allow-env", "E", "", "List of environment variables to pass from client to shell (default: None)")
5354
pflag.CommandLine.StringP("sentry-dsn", "S", "", "Sentry DSN for error reporting")
5455
pflag.CommandLine.IntP("verbosity", "v", 1, "Set verbosity level (0 = quiet, 1 = normal, 2 = verbose, 3 = debug, default: 1)")
5556
pflag.CommandLine.BoolP("version", "", false, "Display version and exit")
@@ -179,7 +180,7 @@ func main() {
179180
server, err := sshproxy.New(
180181
viper.GetString("dir"),
181182
viper.GetString("shell"),
182-
viper.GetBool("allow-env"),
183+
strings.Split(viper.GetString("allow-env"), ","),
183184
shellCreds,
184185
viper.GetInt("verbosity"),
185186
sshConfig,

Diff for: sshproxy.go

+13-9
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type Server struct {
4545
config *ssh.ServerConfig
4646
shell string
4747
shellCreds *syscall.Credential
48-
passEnv bool
48+
envWhitelist map[string]bool
4949
errorHandler ErrorHandler
5050
verbosity int
5151
}
@@ -57,13 +57,13 @@ type ErrorHandler func(error, map[string]string)
5757
// and an ssh.ServerConfig. If no ServerConfig is provided, then
5858
// ServerConfig.NoClientAuth is set to true. ed25519, rsa, ecdsa and dsa
5959
// keys are loaded, and generated if they do not exist. Returns a new Server.
60-
func New(keyDir, shell string, passEnv bool, shellCreds *syscall.Credential, verbosity int, sshConfig *ssh.ServerConfig, errorHandler ErrorHandler) (*Server, error) {
60+
func New(keyDir, shell string, envWhitelist []string, shellCreds *syscall.Credential, verbosity int, sshConfig *ssh.ServerConfig, errorHandler ErrorHandler) (*Server, error) {
6161
s := &Server{
6262
keyDir: keyDir,
6363
config: sshConfig,
6464
shell: shell,
6565
shellCreds: shellCreds,
66-
passEnv: passEnv,
66+
envWhitelist: make(map[string]bool),
6767
errorHandler: errorHandler,
6868
verbosity: verbosity,
6969
}
@@ -72,6 +72,9 @@ func New(keyDir, shell string, passEnv bool, shellCreds *syscall.Credential, ver
7272
NoClientAuth: true,
7373
}
7474
}
75+
for _, envKey := range envWhitelist {
76+
s.envWhitelist[envKey] = true
77+
}
7578
for _, keyType := range []string{"ed25519", "rsa", "ecdsa", "dsa"} {
7679
if err := s.addHostKey(keyType); err != nil {
7780
return nil, err
@@ -211,15 +214,16 @@ func (s *Server) handleRequests(reqs <-chan *ssh.Request, channel ssh.Channel, c
211214
for req := range reqs {
212215
switch req.Type {
213216
case "env":
214-
if s.passEnv {
215-
// append client env to the command environment
216-
keyLen := binary.BigEndian.Uint32(req.Payload[:4])
217-
valLen := binary.BigEndian.Uint32(req.Payload[keyLen+4 : keyLen+8])
218-
key := string(req.Payload[4 : keyLen+4])
217+
// append client env to the command environment
218+
keyLen := binary.BigEndian.Uint32(req.Payload[:4])
219+
valLen := binary.BigEndian.Uint32(req.Payload[keyLen+4 : keyLen+8])
220+
key := string(req.Payload[4 : keyLen+4])
221+
_, ok := s.envWhitelist[key]
222+
if ok {
219223
val := string(req.Payload[keyLen+8 : keyLen+valLen+8])
220224
env = append(env, fmt.Sprintf("%s=%s", key, val))
221225
}
222-
if err := req.Reply(s.passEnv, nil); err != nil {
226+
if err := req.Reply(ok, nil); err != nil {
223227
return err
224228
}
225229
case "pty-req":

0 commit comments

Comments
 (0)