I have an external server make backups of my main server via scp and a backup-only user account. I successfully restricted it to scp only using GNU Rush.

The scp command below executed on the backup server downloads /var/www/website1/file2 from the main server.

scp [email protected]:website1/file2

I want to make sure that user account can download files only from /var/www. I disabled the absolute path downloads, and now have to filter the path itself.

  • I started by removing one or more dots from the file path. Tested this approach, and I can no longer manipulate the input and download website1/../../../etc/passwd.

  • Then I found Alternative ways to exploit this path traversal and added filtering out one or more %, just in case.

Are there any other ways to manipulate the input and get out of the restricted folder that I may be missing and should be aware of?

  • 1
    Is exposing arbitrary named files a required feature? Otherwise I'd just go for archives and whitelisting the possible names (e.g. website1-date.tar.gz). It's hard to blacklist forbidden characters as there are various encoding issues that have to be handled . That said, some webservers allow you to restrict root, and should not allow escapes. Maybe chroot is also an option?
    – domen
    Commented Jan 17, 2020 at 14:09

1 Answer 1


I'm not sure exactly how you are performing your validation, so I can't give detailed steps. However, there is a "best practice" here that I can direct you in anyway.

Principle of Least Privileges

Like all things, it's the difference between blacklisting and whitelisting. The latter is rarely successful. Whitelisting (or more generally, the Principle of Least Privilege) is always the way to go. In essence what this means is that you don't want to try to stop the user from using some list of banned characters. Instead you want to verify that the file/directory that they are actually trying to copy is in the list of permitted files/directories.

Work with the absolute path

They way I do this in similar situations is by taking the user input and "canonicalizing" it - let the OS convert it from a relative path to an absolute path, and then verify that the final, real, absolute path is actually an allowed destination. Once you have an absolute path, verifying that it is an allowed direction is quite easy. In the case of linux I would use something like realpath which does exactly that. I'm not sure if I can guarantee that this approach might not still have edge cases (where realpath ignores an alternate encoding that scp doesn't, potentially leading to a missed exploit), but I suspect the risks will come down substantially. How to actually implement this kind of check in your particular environment is another matter, and I can't help you with that one.

Small Gotcha

Also, you'll have to watch out for symlinks - if someone accidentally puts a symlink in your application that points to /, then scp will happily follow it and try to copy over your entire filesystem.

Another Approach

Of course all the above could be fixed even more easily by having a process run on the server that packages everything and then moves it off into a /backup directory to be copied out (per the comment from @domen)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .