我有两个字符串,都可以由用户设置,例如
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
(如果需要,此解决方案将变得更加乏味,因为您需要记住旧值)。
如果你想精细控制命令运行的环境,你可以在fork
、execve
(或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/