C - 使用环境变量安全执行 system() 或 exec()

标签 c linux

我有两个字符串,都可以由用户设置,例如

char *command = "vim $VAR";
char *myVar = "/tmp/something";

我想使用 *myVar$VAR 执行 *command

我尝试将它们连接为环境变量(例如(伪代码)system("VAR="+ *myVar + "; "+ *command),但用户控制 myVar 所以这将是非常不安全和错误的。

我考虑过对空格进行标记以直接替换 $var 并将结果传递给 exec(),但是担心正确标记 shell 命令参数太尴尬了。

我认为解决方案是通过执行类似 exec("sh", "-c", command, "--argument", "VAR ", myVar),但我在 sh/dash/bash 手册页中看不到任何允许以这种方式设置环境变量的内容。

编辑:我刚刚看到 execvpe(),它有一个参数用于从 key=value 字符串设置环境变量。使用不受信任的值输入是否安全?

我如何安全地执行此操作?

最佳答案

您可以对 myVar 的值执行一些字符串替换 — 将其放在单引号内,并用四个字符替换所有单引号(字符 ')字符串 '\''。如果您不犯实现错误,则繁琐但安全。如果可能的话,use a library that does it for you .

如果您的程序是单线程的,我推荐一个不涉及繁琐引用的不同解决方案。您谈到了设置环境变量……好吧,那就去做吧:将 VAR 设置为环境变量。

setenv("VAR", myVar, 1);
system(command);
unsetenv("VAR")

我省略了错误检查,并且我假设程序中的其他地方不需要 VAR(如果需要,此解决方案将变得更加乏味,因为您需要记住旧值)。

如果你想精细控制命令运行的环境,你可以在forkexecve(或execvpe) 和 waitpid,或者在 posix_spawn(或 posix_spawnp)和 waitpid 之上>。这需要更多的努力,但您可以获得灵 active 。

请注意,除了在 C 程序中对 "vim $VAR" 进行字符串替换之外,无论您采用何种解决方案,命令都需要是 vim "$VAR"而不是 vim $VAR。这是因为在 shell 语法中,$VAR 只有在双引号内时才表示“变量 VAR 的值”——否则,$VAR表示“取 VAR 的值,将其拆分为单词,并将每个单词扩展为文件名通配符模式”。

关于C - 使用环境变量安全执行 system() 或 exec(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24314918/

相关文章:

类型转换有符号为 double 与类型转换为 float 然后 double 结果不同

linux - pcap_next 返回 NULL

linux - 如何在 Linux 的 Perl 中使用带有 fcgi 的 unix 域套接字的抽象名称?

c - 如何(确切地)更改 GCC 目录搜索路径?

c - 使用 "syscall"而不是直接调用函数的原因是什么?

c - 如何在 C 中将字符串与不确定的用户输入分开?

c - 从 C 控制台获取十六进制值

c - C 中合并两个链表时遇到问题

python - 读取用python编写的c二进制文件

linux - 如何在Docker文件中包含Shell脚本套件