我有一个简单的C ++应用程序,用于在另一个用户的特定目录中执行perl脚本。
wrapper my-perl-script.pl
我想确保用户不会尝试通过在前面添加“../”来欺骗C ++应用程序执行特定目录之外的脚本。最好/最简单的方法是什么?
这是我的包装器源的精简版。
int main (int argc, char *argv[])
{
/* set user here */
stringstream userCmd;
userCmd << "/path/to/scripts/";
for ( int i = 1; i < argc; i++ ) {
if ( i == 1) {
// remove instances of ../ from the first argument
userCmd << argv[i]
}
else {
// add user supplied arguments for perl script to command
userCmd << " " << argv[i];
}
}
/* use system to execute the user command */
return 0;
}
答案 0 :(得分:1)
在Linux下,函数realpath()
将为您提供所请求文件的绝对路径,您可以将其与您希望它们能够访问的基本目录的路径进行比较。见这里:realpath manpage
如果用户要提供/path/to/scripts/../../../root/sensitive.sh
,realpath()
会将其转换为/root/sensitive.sh
,您可以将其与允许的目录进行比较,并向用户抛出错误。
答案 1 :(得分:1)
我更喜欢使用字符串而不是原始指针/数组:
int (int argc, char *argv[]) {
std::string path (argv[1]);
if (path.find("..") == std::string::npos)
{
//everything's fine
}
else
std::cout << "No execution in parent directories allowed.";
}
你之所以不切“..”的原因是,如果用户输入类似“../ bad / evenworse / script.sh”的内容,则该路径将不再正确
答案 2 :(得分:0)
答案是不要删除相对路径。如果用户试图传递相对路径或完整系统路径,则它们是恶意的 - 只需终止应用程序。
int main (int argc, char *argv[])
{
if ( argc == 1 || argv[1][0] == '.' || argv[1][0] == '/' ) {
return 0;
}
...
感谢Johnathon Leffler对此解决方案的评论。