【问题标题】:C++: How to escape user input for safe system calls?C++:如何为安全的系统调用转义用户输入?
【发布时间】:2011-04-05 09:40:45
【问题描述】:

在 Linux 平台上,我的 C++ 代码如下所示:

// ...
std::string myDir;
myDir = argv[1]; // myDir is initialized using user input from the command line.
std::string command;
command = "mkdir " + myDir;
if (system(command.c_str()) != 0) {
   return 1;
}
// continue....
  • 将用户输入传递给 system() 调用是否安全?
  • 是否应该对用户输入进行转义/清理?
  • 怎么样?
  • 上述代码如何被恶意利用?

谢谢。

【问题讨论】:

    标签: c++ linux security escaping


    【解决方案1】:

    除了 Matthew 的回答之外,除非绝对需要,否则不要生成 shell 进程。如果您使用 fork/execl 组合,则永远不会解析单个参数,因此不需要转义。但请注意空字符,它仍会过早终止参数(在某些情况下这不是安全问题)。

    我假设 mkdir 只是一个示例,因为 mkdir 可以比这些子进程建议更容易地从 C++ 中调用。

    【讨论】:

      【解决方案2】:

      只是不要使用system。首选execl

      execl ("/bin/mkdir", "mkdir", myDir, (char *)0);
      

      这样,myDir 总是作为单个参数传递给mkdir,并且不涉及 shell。请注意,如果使用此方法,则需要fork

      但如果这不仅仅是一个例子,你应该使用mkdir C 函数:

      mkdir(myDir, someMode);
      

      【讨论】:

      • 请注意,如果没有发生错误,execl 不会返回(与 system 不同)。您必须首先fork,在父进程中等待子进程完成并最终从父进程检查execl 的返回值。
      • 谢谢。如果我使用 mkdir(myDir, someMode),myDir 不需要清理或转义?无论用户输入什么都安全吗?
      • 是的,mkdir C 函数只需要一个目录名称。无论如何,它都会尝试创建一个目录。
      • augustin:可能不安全。如果您的程序以 root 用户身份运行,例如让您的程序创建顶级目录等。您可能应该检查路径名等中是否有斜杠。或者甚至像以下限制一样:如果目录名不只包含字符、字母、下划线和一些其他字符你认为安全,拒绝运行 mkdir。
      • @Andre,或最小化程序以 root 身份执行的操作。即使部分程序需要root,目录创建代码也不一定。
      【解决方案3】:

      在不清理输入的情况下使用带有命令行参数的 system() 调用可能非常不安全。

      潜在的安全威胁可能是用户将以下内容作为目录名称传递

      somedir ; rm -rf /
      

      为防止这种情况,请混合使用以下内容

      • 使用 getopt 确保您的输入是 已消毒
      • 清理输入
      • 使用 execl 代替 system 执行 命令

      最好的选择是使用所有三个

      【讨论】:

      • 感谢漏洞利用示例。这很清楚! ;) 实际上,myDir 是为 getopt 而来的,尽管我没有在上面的代码中显示它。我将检查如何使用 execl:显然,需要一个 fork(根据此处的另一条评论)。
      • 不要尝试转义字符串并使用 execl - 这会导致传递错误的参数。
      猜你喜欢
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      • 2014-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多