C++ 如何转义发送到';系统&x27;C++;?
讨论如何使用C++ 如何转义发送到';系统&x27;C++;?,c++,linux,escaping,C++,Linux,Escaping,讨论如何使用系统命令和传递变量。下面是一个例子: string cmd("curl -b cookie.txt -d test="); cmd += line; cmd += " http://example.com"; system(cmd.c_str()); 其中一条评论提到,如果line被传递并包含foo&fire\u nukes.exe&REM,那么很可能会发生不好的事情 PHP有一个名为escape\u shell\u args的强大函数,可用于转义传递给程序的参数。C++有办法吗
系统
命令和传递变量。下面是一个例子:
string cmd("curl -b cookie.txt -d test=");
cmd += line;
cmd += " http://example.com";
system(cmd.c_str());
其中一条评论提到,如果line
被传递并包含foo&fire\u nukes.exe&REM
,那么很可能会发生不好的事情
PHP有一个名为
escape\u shell\u args
的强大函数,可用于转义传递给程序的参数。C++有办法吗?< P>最好的办法是不要使用<代码> Stand()< /C>。使用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. */
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int fork_curl(字符*行)
{
std::string linearg(“line=”);
linearg+=直线;
int-pid=fork();
如果(pid!=0){
/*我们在父进程中,返回子进程的pid*/
返回pid;
}
/*否则,我们处于子进程中,所以让我们执行curl*/
execlp(“curl”、“-b”、“cookie.txt”、“-d”、linearg.c_str());
/*执行官不应该回来,所以
一定是出了问题*/
出口(100);
/*注意:您可能应该使用退出状态
如果可能的话,这不会与curl使用的这些冲突*/
}
int main(int argc,char*argv[])
{
int cpid=叉形卷曲(“测试”);
如果(cpid==-1){
/*未能分叉*/
错误(1,errno,“Fork失败”);
返回1;
}
/*(可选)等待子级退出并获取
退出状态*/
智力状态;
waitpid(cpid和状态,0);
如果(!妻子退出(状态)){
错误(1,0,“该子项已被杀死或出现故障或其他\n”);
}
状态=WEXITSTATUS(状态);
/*状态现在包含子进程的退出状态*/
}
您可以试试execl
#包括
int execl(常量字符*路径,常量字符*参数,…);
切勿将用户输入传递给系统
呼叫。永远
你可以尝试逃避所有你认为危险的角色,但你会弄错的
相反,从另一个方向着手:让用户提供您定义的任何输入选择,然后进行切换
,从头开始构建您自己的系统调用
诚然,当要调用的命令行应用程序的输入是自由形式的时,这会变得有点棘手,但这正是实际库的用途
libcurl
,有人吗?请参阅手册页,其中列出了所有(系统调用不是派生shell的system(3)
函数)
了解更多有关和的信息,以及
回到您的问题,您可以引用shell(只需按照shell转义规则转换字符串;例如,在任何非字母字符前面加反斜杠)
另请参见的手册页等
读一本关于名人的好书
在Linux发行版上自由使用大多数软件。例如,您可以研究像sash
这样的简单shell的源代码
也许你只是想用curl。然后最好的方法是为库编码(无需调用系统(3)
)
学习这一切都很有趣 您可以使用环境变量将参数安全地传递给COM,并由
系统执行(3)
这两个邪恶的代码都不会被执行,只是简单地打印出来。你能提供我应该使用的那些命令文档的链接吗?或者给出一个如何使用这些命令的例子?举个例子就好了:)@SteveBrown我已经添加了一个例子。Nooooooo!execl替换了当前进程,而fork()在某些平台上的定义非常糟糕。真的不!但是,如果命令是一个shell脚本(带有#!/bin/bash和chmod 777),那么您仍然必须转义参数,否则您会得到/bin/bash:-c:line 0:syntax error靠近意外标记“”(“您可以始终使用
fork
和exec
…man fork
,man exec
:-)(您不能真正说如果你不知道man
!man3exec
,那么你可以说:man
?你可能应该使用C@KerrekSB的libcurl不,你不应该!不是每个人都使用Linux!系统是
的一部分,但是没有独立于平台的fork,exec(AFAIK).我知道系统
是邪恶的,但你知道它是邪恶的,…并且实际上存在于Windows上(没有cygwin)。如果你需要将传递给你的程序的变量传递给另一个程序呢?也许是一个文件路径?这就是我试图做的。我还没有这样做的原因是因为我知道它不“安全”“因此,我想找出一个安全的(呃)方法。谢谢。你的意思是对系统(3)的调用,而不是像系统调用(2)那样的系统调用。也许这就是我需要的。如果我想将传递给程序的变量传递给/bin/echo
命令,我该怎么做?(毫无意义,但让我们以它为例)您应该定义变量对您意味着什么。一旦你在头脑中很好地理解了它们的意思,你就几乎解决了问题。问题是,即使逃避每一个非字母也是不够的。如果一个恶意用户启动一个带有修改路径和/或IFS的setuid程序怎么办?我同意,但至少它回答了这个问题。我的感觉是,海报不应该使用system
也不应该使用curl
过程,而是应该学会从libcurl
调用函数,剩下的答案很好。但是,真的,system()
真的很危险。是的,我同意使用system
是错误的方法。我知道这很危险。但这正是原海报想象的他想要的。(我的观点是,他只需要了解libcurl)。你的前两段没有相关性
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
setenv ("mypar1", "'$(rm -rf /)", 1);
setenv ("mypar2", "\"; rm -rf /", 1);
system ("echo mypar1=\"$mypar1\" mypar2=\"$mypar2\");