This question讨论使用system
命令并传递变量。这是一个例子:
string cmd("curl -b cookie.txt -d test=");
cmd += line;
cmd += " http://example.com";
system(cmd.c_str());
其中一条评论提到,如果line
被传递并包含foo & fire_nukes.exe & REM
,那么很可能发生一些不好的事情。
PHP有一个很好的函数叫escape_shell_args
,它可以用来转义传递给程序的参数。 C ++有办法做到吗?
答案 0 :(得分:4)
最好的方法是不要使用system()
。使用fork()
和exec()
以及朋友。
这是一个例子:
#include <string>
#include <unistd.h>
#include <error.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <cstdlib>
int fork_curl(char *line)
{
std::string linearg("line=");
linearg += line;
int pid = fork();
if(pid != 0) {
/* We're in the parent process, return the child's pid. */
return pid;
}
/* Otherwise, we're in the child process, so let's exec curl. */
execlp("curl", "-b", "cookie.txt", "-d", linearg.c_str());
/* exec is not supposed to return, so something
must have gone wrong. */
exit(100);
/* Note: You should probably use an exit status
that doesn't collide with these used by curl, if possible. */
}
int main(int argc, char* argv[])
{
int cpid = fork_curl("test");
if(cpid == -1) {
/* Failed to fork */
error(1, errno, "Fork failed");
return 1;
}
/* Optionally, wait for the child to exit and get
the exit status. */
int status;
waitpid(cpid, &status, 0);
if(! WIFEXITED(status)) {
error(1, 0, "The child was killed or segfaulted or something\n");
}
status = WEXITSTATUS(status);
/* Status now contains the exit status of the child process. */
}
答案 1 :(得分:4)
切勿将用户输入传递到system
来电。如初。
你可以试图逃避你认为危险的所有角色,但你会弄错。
相反,从另一个方向继续:让用户提供你定义的任何输入选择,然后执行switch
并从头开始构建自己的系统调用
不可否认,当要调用的命令行应用程序的输入是自由形式时,这有点棘手,但是,这就是实际库的用途。 libcurl
,有人吗?
答案 2 :(得分:0)
你可以试试execl ..
http://linux.about.com/library/cmd/blcmdl3_execvp.htm
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
答案 3 :(得分:0)
请参阅列出所有syscalls的手册页(系统调用不是伪造shell的system(3)
函数。)
详细了解system calls和linux kernel以及operating systems的整体组织
回到你的问题,你可以引用shell(只需遵循shell转义规则来转换你的字符串;例如,用反斜杠作为前缀任何非字母字符)。
在advanced linux programming和着名的Advanced Unix Programming
上阅读一本好书在Linux发行版上使用大多数软件的自由。例如,您可以研究像sash
这样的简单shell的源代码。
也许你只想使用卷曲。然后,最好的方法是代码libcurl库(无需调用system(3)
)
尽情学习这一切!
答案 4 :(得分:0)
您可以使用环境变量将参数安全地传递给system(3)
执行的命令。
setenv ("mypar1", "'$(rm -rf /)", 1);
setenv ("mypar2", "\"; rm -rf /", 1);
system ("echo mypar1=\"$mypar1\" mypar2=\"$mypar2\");
这些邪恶代码都不会执行,只需打印即可。