【问题标题】:Is glibc's system() call safe?glibc 的 system() 调用安全吗?
【发布时间】:2012-05-04 22:04:26
【问题描述】:

我听到有人说来自libcsystem() 呼叫不安全。

我能想到的一个原因是它启动了 shell 实用程序,例如/bin/bash 并且如果 system("rm -rf $input") 已启动并且 $input 是未经处理的用户输入,那么如果 $input="/" 可能会造成严重破坏。 还有什么其他原因?

【问题讨论】:

  • @Mat 当输入被严格输入和清理时不会
  • @NulledPointer 我希望您所说的“净化”是指“列入白名单”。否则......好吧,让我们说它比你想象的要难。
  • @CharlesDuffy 他们之间确实有很大的不同。是的,它们被“列入白名单”。它与您如何指定 sudoer 可以执行的命令列表完全一样(来自 /etc/sudoers)。
  • @CharlesDuffy 另外我认为我们应该求助于fork()exec() 而不是懒惰并致电system()

标签: c linux bash unix glibc


【解决方案1】:

通常,“安全”是与exec 系列系统调用(execve() 是最低级别的标准调用)相比;涉及 shell 不仅意味着未清理数据的问题,而且还意味着 $PATH(你知道你在执行什么吗?)和 $IFS(这是一个有趣的问题:如果有人可以改变 @ 987654325@ 你,shell 不会像你期望的那样解析东西)。

【讨论】:

  • IFS 实际上比大多数人想象的要少得多。它可能很危险,但不像你第一次读到它时听起来那么疯狂。其他问题要大得多..
【解决方案2】:

您甚至不必调用 rm 进行恶意输入来擦除硬盘驱动器。如果您执行system("harmless_command $input") 并且$input; rm -rf /,则将执行harmless_command 后跟rm -rf /。因此,如果您想在命令中插入用户输入并且恶意输入将是一个问题¹,那么使用 system 将是一个坏主意。

除了安全问题,使用系统也可能导致错误。例如,如果您执行 system("some_command $filename") 并且 $filename 包含空格(或其他 shell 元字符),则除非您先正确转义文件名,否则该命令将崩溃。

如果您使用 exec* 系列函数(它采用包含命令参数的数组或可变参数列表,而不是通过 shell 的单个字符串),则不存在这些问题。


¹ 如果代码以用户的权限在用户的计算机上运行,​​人们可能会争辩说恶意输入不会成为问题。如果用户输入恶意输入导致他的硬盘被擦除,那真的是用户自己的错。但如果代码在远程服务器上运行,或者在本地以增强的权限运行,那就另当别论了。

【讨论】:

    【解决方案3】:

    这是输入完整性检查的一般情况。您使用的任何字符串都应该有一个通用解析器来过滤掉转义序列等。例如,所有体面的 PHP 应用程序在调用 SQL 数据库之前都会这样做。

    您提到的第一种情况非常明显:有人可以破坏您的系统。另一个是如果你可以得到一组二进制代码,覆盖你的代码中的指令/函数,并让你的程序做一些完全不同的事情(即:这就是越狱/根攻击的工作方式)。有关此特定威胁的更多信息,您应该阅读缓冲区溢出和代码注入漏洞: http://en.wikipedia.org/wiki/Code_injection

    另外,这里有一个代码注入的例子: Understanding and doing Code Injection in C

    【讨论】:

    • "所有体面的 PHP 应用程序在调用 SQL 数据库之前都会这样做" 实际上我希望体面的 PHP 应用程序使用准备好的 SQL 语句而不是执行任何 SQL 转义(或使用现有的转义函数) )。同样,我希望体面的应用程序通过类似 exec 的函数传递用户参数,而不是使用系统和手动清理参数。
    • 同意。我的意思是,一般来说,任何接受用户直接输入的东西都会对其进行清理以删除任何意外的东西(例如:转义序列、机器代码等)
    • @Dogbert 如果您依靠消毒来确保安全,那么您做错了。遵循上述 sepp2k 提出的做法,无需进行清理。
    【解决方案4】:

    不可能知道“某人”在想什么,但可能是因为 system() 通过 shell 运行命令,这可能导致最终的命令执行与您计划的不同。例如,您不知道 PATH 环境变量将被设置为什么,以及许多其他可更改的东西。

    坚持使用 exec 的变体,但即便如此,也要非常小心传递给它们的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-03
      • 2018-04-11
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 2015-09-20
      • 2017-07-08
      • 2012-10-25
      相关资源
      最近更新 更多