glibc的system()调用安全吗?

时间:2012-05-04 22:04:26

标签: c linux bash unix glibc

我听到有人说来自system()的{​​{1}}电话不安全。

我能想到的一个原因是它启动了shell实用程序,例如libc如果启动/bin/bash并且$ input是未清理的用户输入,那么如果$ input =“/”则可能会造成严重破坏。 还有什么其他原因?

4 个答案:

答案 0 :(得分:3)

通常,“安全”与exec系列调用相比较(execve()是最低级别的标准调用);涉及shell不仅意味着未使用数据的问题,还意味着$PATH(你知道你正在执行什么?)和$IFS(这是一个有趣的数据:如果有人可以改变你$IFS,shell不会按你期望的方式解析事物。

答案 1 :(得分:3)

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

除了安全问题,使用系统还可能导致错误。例如,如果你system("some_command $filename")和$ filename包含空格(或其他shell元字符),除非你先正确地转义文件名,否则命令会爆炸。

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


¹如果代码在用户的计算机上以用户的权限运行,可以说恶意输入不会成为问题。如果用户输入导致其硬盘被擦除的恶意输入,则这确实是用户自己的错误。但是,如果代码在远程服务器上运行或在本地具有增强的权限,那么这是另一回事。

答案 2 :(得分:2)

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

你提到的第一个案例非常明显:有人可以摧毁你的系统。另一个问题是,如果您可以获得一组二进制代码来覆盖代码中的指令/函数,并让您的程序完全不同(例如:这是越狱/ root攻击的工作原理)。有关此特定威胁的更多信息,您应该阅读缓冲区溢出和代码注入漏洞: http://en.wikipedia.org/wiki/Code_injection

此外,还有一个代码注入示例: Understanding and doing Code Injection in C

答案 3 :(得分:0)

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

坚持exec的变化,但即便如此,要非常小心你传递给他们的东西。