summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Allbery <rra@debian.org>2019-01-17 19:21:40 -0800
committerRuss Allbery <rra@debian.org>2019-02-18 18:58:27 -0800
commited1e79552f31124064f9c6f6c7913ca442563f39 (patch)
treea4a3ecd14781924b618ae08250bdb1d222786221
parenteeaed683aaf2d4c1801f9ffc0ab755b00a898ada (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.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/util.c b/util.c
index 52a751b..da97592 100644
--- a/util.c
+++ b/util.c
@@ -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;
}