1

我有一个简单的 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;
 }
4

3 回答 3

1

在 Linux 下,该函数realpath()将为您提供所请求文件的绝对路径,您可以将其与您希望它们能够访问的基本目录的路径进行比较。请参见此处:realpath 手册页

如果用户提供/path/to/scripts/../../../root/sensitive.sh,realpath()会将其转换/root/sensitive.sh为您可以与允许的目录进行比较的目录并向用户抛出错误。

于 2013-05-29T17:33:44.527 回答
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”之类的内容,路径将不再正确

于 2013-05-29T21:20:02.543 回答
0

答案是不要删除相对路径。如果用户试图传递相对路径或完整的系统路径,那么他们就是恶意的 - 只需终止应用程序。

int  main (int argc, char *argv[])
{

  if ( argc == 1 || argv[1][0] == '.' || argv[1][0] == '/' ) {
     return 0;
  }

  ...

感谢 Johnathon Leffler 对此解决方案的评论。

于 2013-05-29T19:13:09.000 回答