【问题标题】:popen vs. KornShell securitypopen 与 KornShell 安全性
【发布时间】:2025-12-02 17:50:01
【问题描述】:

我正在编写一个 C 程序,使用一些外部二进制文件来实现计划目标。我需要运行一个命令给我一个输出,然后我需要处理它,然后作为输入输入另一个程序。我正在使用 popen,但想知道这是否与使用 KornShell (ksh) 临时文件相同。

例如:

touch myfile && chmod 700
cat myfile > /tmp/tempfile 
process_file < /tmp/tempfile  && rm /tmp/tempfile

既然创建了一个root可以读取的临时文件,那么如果在C中使用popen,知道管道也是文件,会不会一样?或者假设操作系统 (OS) 不允许任何其他进程读取您的管道是否安全?

【问题讨论】:

  • 不要使用700权限;您没有创建可执行文件。使用 600。

标签: c shell unix ksh popen


【解决方案1】:

您说“这会创建一个 root 用户可以读取的临时文件”,这意味着您正在尝试以 root 用户无法读取的方式传输数据。这不可能;一般来说,root 用户完全控制系统,因此可以读取系统上的任何数据,无论它是否在临时文件中。即使在单个进程中,root 用户也可以读取该进程的内存。

如果您使用popen(),则文件系统上不会有该文件的条目;它创建了一个管道,其作用类似于文件,但实际上并不将该数据写入磁盘,而只是在两个程序之间传递它。

它会有一个文件描述符;根据系统的不同,截取该数据可能更容易或更难,但始终可以这样做。例如,在 Linux 上,您只需查看 /proc/&lt;pid&gt;/fd/ 即可找到所有打开的文件描述符并对其进行操作(读取或写入)。

【讨论】:

  • 感谢 Brian,关注的不是具有 root 访问权限的人类用户读取文件,而是进程分离。我试图找出编写处理敏感数据的程序的最安全方法是什么。例如,有人可能会建议共享内存作为更好的选择(我不是经验丰富的程序员,因此我不知道)。任何建议表示赞赏。
  • @user1944224 创建管道(使用popen)会将所有数据保存在内存中;它永远不会将其写入磁盘(除非作为交换,但内存中的任何数据都是如此)。它也不会在任何文件系统上为其创建文件。所以从这个意义上说,它更安全,因为您不太可能意外暴露文件(如果您不小心,将文件写入/tmp 会出现各种问题)。没有什么可以保护您的数据免受试图从您的程序中提取数据的以 root 身份运行的程序的影响;不管你如何沟通,一个特权进程可以直接读取你的内存。
  • 虽然 Linux 为匿名管道创建了一个 inode,但它在文件系统上不可见(与命名管道/fifo 不同)。匿名管道只能在相关进程(父子进程、兄弟进程或类似进程)之间使用。
  • 在 Linux 以外的许多系统上,管道比共享内存更难读取; root 可以附加到共享内存来读取它。在 Linux 上,管道可能仍然难以拦截;读取会破坏数据,因此如果root 读取信息,另一个进程根本看不到它。
  • @JonathanLeffler 虽然 root 从管道中读取可能不太方便,但这并不是那么难。他们只需调用tee 即可从管道中复制数据而不使用它。或者他们可以附加到您的进程并跟踪它的系统调用。或者从您的进程的/proc/$pid/mem 中读取数据。或任何其他获取数据的方法。