when a source file name listed on the rsync command line contains | or ; then whatever comes after is executed as a command on the remote machine. rsync somehost:/foobar\;date\>/tmp/date . (note the backslashes) will fail and leave behind the file /tmp/date on the somehost. this can cause serious trouble when file names can be picked by untrusted users. the problem doesn't seem to occur when evil file names occur in a tree being copied or when given as copy source.
This is not a security problem because for it to occur, the user needs to have ssh access to the host, so you're already trusting them for that. If you are limiting what they can do via ssh, it is up to you to ensure that the command they specified is safe, not rsync (since it is the shell that is processing those characters -- rsync never sees them).
I think Urban is talking about a script that runs an rsync-over-ssh client on behalf of an untrusted caller, in which case the ability to run arbitrary remote commands would be a vulnerability in the script. Urban, to prevent the command execution, you can add --protect-args to the script. Then rsync won't pass the filenames through the remote shell, but the remote rsync will expand globs itself. If you don't even want globbing, use --files-from and perhaps --from0. I don't think a change to rsync is needed.
@Wayne: Yes it is a security problem. Scenario: The user is in an apache+php process and needs to copy around arbitrarily named files he just uploaded on a cluster. The cluster allows password free login every host to every other host, which is perfectly safe as long as any commands executed are chosen by php. At no point did we give the user permission to execute arbitrary commands! We just allow him to copy a file named by him, that's a completely different security level. However if that name contains certain characters, he can escalate his privilege using rsync. Imagine he uploads a file named ';rm -rf ..' All other unix tools handle this case without problems if the file name is escaped correctly, just rsync (and scp) have a problem. --protect-args does solve the problem but not everyone knows about or remembers to use it. I see no reason why dangerous characters can't ALWAYS be escaped before passing the args to the shell for globbing. I'd escape everything but \w * ? [ ] { }
If you don't trust your users, you need to setup something better on your part, such as forcing the -s (--protect-args) option on all rsync commands that get run on the client and using a different shell (or forced wrapper script) on the remote hosts that ensures the safety of the command-line. When doing an ssh transfer, rsync assumes that you to know what you're doing. It does not know what shell is on the other side, so asking it to escape chars in an undefined manner is not something that it can do portably (so if we build in bourne-shell escaping, that could break the use of a more rare shell setup). I recommend a safety script on the remote hosts to ensure that nothing tricky is going on. Rsync supplies a script named rrsync in the support directory that handles safe globbing of filenames without allowing a shell to interpret special characters (since it completely avoids the spawning of a shell). If you setup the ssh logins to force the command to go to the rrsync perl script, it can both validate the command-line options and safely handle the file args for you. Rsync also supports daemon mode (including daemon over ssh) for being the most safe and restrictive. Because making ssh transfers safe takes setup outside of rsync, I am marking this bug request as wontfix.