我听到有人说system()
打来的电话libc
不安全。
我能想到的一个原因是它启动了 shell 实用程序,例如/bin/bash
,如果system("rm -rf $input")
已启动并且 $input 是未经处理的用户输入,那么如果 $input="/" 则它可能会造成严重破坏。其他原因是什么?
您甚至不必调用 rm 进行恶意输入来擦除硬盘驱动器。如果您执行system("harmless_command $input")
and $input
is ; rm -rf /
,那将执行harmless_command
后跟rm -rf /
. 因此,如果您想在命令中插入用户输入并且恶意输入将是一个问题¹,那么使用 system 将是一个坏主意。
除了安全问题,使用系统也可能导致错误。例如,如果您这样做system("some_command $filename")
并且 $filename 包含空格(或其他 shell 元字符),则该命令将爆炸,除非您先正确转义文件名。
如果您使用 exec* 系列函数(它采用包含命令参数的数组或可变参数列表,而不是通过 shell 的单个字符串),则不存在这些问题。
¹ 如果代码在用户许可的情况下在用户计算机上运行,人们可能会争辩说恶意输入不会成为问题。如果用户输入恶意输入导致他的硬盘被擦除,那真的是用户自己的错。但是,如果代码在远程服务器上运行或在本地以增强的权限运行,那就另当别论了。
一般来说,“安全”是与exec
系统调用系列(execve()
是最低级别的标准)相比;涉及 shell 不仅意味着未清理数据的问题,而且还意味着$PATH
(你知道自己在执行什么吗?)和$IFS
(这是一个有趣的问题:如果有人可以改变$IFS
你,shell 不会按照你期望的方式解析事物)。
这是输入完整性检查的一般情况。您使用的任何字符串都应该有一个通用解析器来过滤掉转义序列等。例如,所有体面的 PHP 应用程序在调用 SQL 数据库之前都会这样做。
您提到的第一种情况很明显:有人可以破坏您的系统。另一个是如果你可以得到一组二进制代码,覆盖你的代码中的指令/功能,并让你的程序做一些完全不同的事情(即:这就是越狱/根攻击的工作方式)。有关此特定威胁的更多信息,您应该阅读缓冲区溢出和代码注入漏洞: http ://en.wikipedia.org/wiki/Code_injection
另外,这里有一个代码注入的例子: Understanding and doing Code Injection in C
不可能知道“某人”在想什么,但可能是因为 system() 通过 shell 运行命令,这可能导致最终的命令执行与您计划的不同。例如,您不知道 PATH 环境变量将被设置为什么,以及许多其他可更改的东西。
坚持使用 exec 的变体,但即便如此,也要非常小心传递给他们的内容。