如何使用Net :: OpenSSH安全地写入远程文件

时间:2015-04-19 23:24:48

标签: perl shell security ssh directory-traversal

假设应用程序服务器从客户端接收二进制blob并将其写入远程主机上的文件。

client -(HTTP)> application server -(SSH)> remote data host

鉴于文件名是来自客户端的用户输入,必须在(app)服务器上做些什么来防止攻击(目录遍历攻击)?

用于连接远程主机的用户帐户有一个主目录/home/datauser,不应访问其家外的任何内容。

这是代码:

# User input
my $name = ...; # bob's car.jpg
my $dir = ...; # pics/vacation "country"/

# Slashes are illegal
die "Illegal dir" if ($dir =~ /\.\.\//); # ../ is an attack
die "Illegal name" if ($name =~ /\//); # / in file name is an attack

# Escape single quotes
my $safe_path = $dir.$name;
$safe_path =~ s/'/'\\''/g;

# my $ssh = Net::OpenSSH->new(...);
my $root_dir = '/home/datauseruser';
my $cmd =
    "cd '$root_dir' && ".
    "cat >>'$safe_path'";
$ssh->system({stdin_data => $bytes}, $cmd);

这是一个好方法吗?是否有更多漏洞?

注意:需要随机访问,因此无法使用scp。

1 个答案:

答案 0 :(得分:0)

通过SSH连接发送内容的市长潜在安全问题是远程shell是不可避免的。换句话说,每当您要求SSH执行命令时,而不仅仅fork+exec执行给定命令(@CMD),它实际上会调用shell($LOGIN_SHELL -c $CMD) ,所以必须正确引用命令参数。

你自己已经在做引用了,代码对我来说似乎是正确的。但无论如何,你可以让Net :: OpenSSH为你做这件事并且不用担心:

my $safe_path = $ssh->shell_quote($path);
$ssh->system("cat >>$safe_path");

最后,实际上,有一种方法可以避免使用shell:使用SFTP。

Net :: OpenSSH与Net :: SFTP :: Foreign集成,您可以使用它轻松访问远程文件系统。