Why does scp’s strict filename checking reject quoted last component but not others

filenamesquotingscp

When I try to scp a file with a slash in its path, the path is quoted for the local host, and the last path component is additionally quoted for the remote host, like scp host:"a/b/'c'" ., it fails with

protocol error: filename does not match request

unless I use the -T option. However, if any other path component is quoted, like scp host:"a/'b'/c" ., it works. Also, if the path is not quoted for the local host, like scp host:a/b/'c' ., it works.

The man page documents -T as:

Disable strict filename checking. By default when copying files from a remote host to a local directory scp checks that the received filenames match those requested on the command-line to prevent the remote end from sending unexpected or unwanted files. Because of differences in how various operating systems and shells interpret filename wildcards, these checks may cause wanted files to be rejected. This option disables these checks at the expense of fully trusting that the server will not send unexpected filenames.

I don't understand how this description explains the behavior I see. What is the rationale for scp's behavior? And is there any way to disable this "feature"?

I am running Ubuntu 16.04 and the remote host is running Ubuntu 12.04.

Best Answer

Ubuntu people are known for pushing through inconsiderate/partial patches (recent example); in your case, it's about this patch, which is less than 3 weeks old, including the time spent in snapshots:

check in scp client that filenames sent during remote->local directory
copies satisfy the wildcard specified by the user.

This checking provides some protection against a malicious server
sending unexpected filenames, but it comes at a risk of rejecting wanted
files due to differences between client and server wildcard expansion rules.

For this reason, this also adds a new -T flag to disable the check.

reported by Harry Sintonen
fix approach suggested by markus@;
has been in snaps for ~1wk courtesy deraadt@

OpenBSD-Commit-ID: 00f44b50d2be8e321973f3c6d014260f8f7a8eda

That is not ready for prime time (it's naively using fnmatch(3) on the basename of the file) and already had to fixed to allow for brace expansions.

Conclusion: it's a bug; it'll probably be fixed sooner or later; or if not, be prepared to always disable this new misfeature with -T.

Related Question