diff options
author | Russ Allbery <rra@debian.org> | 2019-01-17 19:21:40 -0800 |
---|---|---|
committer | Russ Allbery <rra@debian.org> | 2019-02-18 18:58:27 -0800 |
commit | ed1e79552f31124064f9c6f6c7913ca442563f39 (patch) | |
tree | a4a3ecd14781924b618ae08250bdb1d222786221 | |
parent | eeaed683aaf2d4c1801f9ffc0ab755b00a898ada (diff) |
Verify scp command options
ESnet discovered a security vulnerability in the scp backend for
rssh. Since the arguments to scp on the server side were not
checked, the client could pass in arbitrary scp command-line flags,
including setting arbitrary scp options. This allows setting the
option PKCS11Provider, which loads and executes code from a shared
module.
Even if the -o flag is blocked, this is still possible via -F to
load an already-uploaded ssh configuration file, or, if .ssh/config
is writable, by just uploading that configuration file directly
first.
Attempt to protect against this attack by checking the command line
of scp and only allowing the options that are passed to the server
end of the connection. Require either -f or -t be given, which
disables scp's attempts to connect to a remote host. Allow these as
-pf and -pt, which are sent by libssh2.
Debian Bug#919623
Gbp-Pq: Name 0009-Verify-scp-command-options.patch
-rw-r--r-- | util.c | 44 |
1 files changed, 42 insertions, 2 deletions
@@ -264,6 +264,43 @@ static int rsync_okay( char **vec ) /* + * scp_okay() - take the command line and check that it is a hopefully-safe scp + * server command line, accepting only very specific options. + * Returns FALSE if the command line should not be allowed, TRUE + * if it is okay. + */ +static int scp_okay( char **vec ) +{ + int saw_f_or_t = FALSE; + + for ( vec++; vec && *vec; vec++ ){ + /* Allowed options. */ + if ( strcmp(*vec, "-v") == 0 ) continue; + if ( strcmp(*vec, "-r") == 0 ) continue; + if ( strcmp(*vec, "-p") == 0 ) continue; + if ( strcmp(*vec, "-d") == 0 ) continue; + if ( strcmp(*vec, "-f") == 0 || strcmp(*vec, "-pf") == 0 ){ + saw_f_or_t = TRUE; + continue; + } + if ( strcmp(*vec, "-t") == 0 || strcmp(*vec, "-pt") == 0 ){ + saw_f_or_t = TRUE; + continue; + } + + /* End of arguments. */ + if ( strcmp(*vec, "--") == 0 ) break; + + /* Any other argument is not allowed. */ + if ( *vec[0] == '-' ) return FALSE; + } + + /* Either -f or -t must have been given. */ + return saw_f_or_t; +} + + +/* * check_command_line() - take the command line passed to rssh, and verify * that the specified command is one the user is * allowed to run and validate the arguments. Return the @@ -278,8 +315,11 @@ char *check_command_line( char **cl, ShellOptions_t *opts ) return PATH_SFTP_SERVER; if ( check_command(*cl, opts, PATH_SCP, RSSH_ALLOW_SCP) ){ - /* filter -S option */ - if ( opt_filter(cl, 'S') ) return NULL; + if ( !scp_okay(cl) ){ + fprintf(stderr, "\ninsecure scp option not allowed."); + log_msg("insecure scp option in scp command line"); + return NULL; + } return PATH_SCP; } |