如何转义发送到“系统”的变量? C++ 中的命令?

发布于 2024-12-21 09:52:55 字数 477 浏览 2 评论 0原文

这个问题讨论使用 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++有办法做到这一点吗?

This question talks about using the system command and passing variables. Here is an example it gives:

string cmd("curl -b cookie.txt -d test=");
cmd += line;
cmd += "  http://example.com";
system(cmd.c_str());

One of the comments mentions that if line was passed and contained foo & fire_nukes.exe & REM then it's quite possible something bad could happen.

PHP has a great function called escape_shell_args which can be used to escape parameters that are being passed to the program. Does C++ have a way to do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

街角卖回忆 2024-12-28 09:52:55

最好的方法是根本不使用 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. */
}

The best way is not to use system() at all. Use fork() and exec() and friends.
Here's an example:

#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. */
}
二智少女 2024-12-28 09:52:55

切勿将用户输入传递给系统调用。曾经。

你可以尝试逃避所有你认为危险的角色,但你会出错。

相反,从另一个方向进行:让用户提供您定义的任何输入选择,然后进行切换并从头开始构建您自己的系统调用。

诚然,当要调用的命令行应用程序的输入是自由格式时,这会变得有点棘手,但是,这就是实际库的用途。 libcurl,有人吗?

Never pass user input into a system call. Ever.

You can try to escape all the characters that you think are dangerous, but you will get it wrong.

Instead, go at it from the other direction: let the user provide any of a selection of inputs that you define, then do a switch and build your own system call from scratch.

Admittedly this gets a little tricky when the input to the command-line application to invoke is freeform but, well, that's what actual libraries are for. libcurl, anyone?

べ繥欢鉨o。 2024-12-28 09:52:55

您可以使用环境变量将参数安全地传递给system(3)执行的命令,

setenv ("mypar1", "'$(rm -rf /)", 1);
setenv ("mypar2", "\"; rm -rf /", 1);
system ("echo mypar1=\"$mypar1\" mypar2=\"$mypar2\");

这些邪恶代码都不会被执行,只是打印出来。

You can use environment variables to safely pass parameters to the comand executed by system(3)

setenv ("mypar1", "'$(rm -rf /)", 1);
setenv ("mypar2", "\"; rm -rf /", 1);
system ("echo mypar1=\"$mypar1\" mypar2=\"$mypar2\");

Neither of these evil codes will be executed, simply printed.

木森分化 2024-12-28 09:52:55

你可以尝试 execl ..

http://linux.about.com/library/cmd/blcmdl3_execvp .htm

#include <unistd.h> 

int execl(const char *path, const char *arg, ...); 

You could try execl..

http://linux.about.com/library/cmd/blcmdl3_execvp.htm

#include <unistd.h> 

int execl(const char *path, const char *arg, ...); 
茶花眉 2024-12-28 09:52:55

请参阅列出所有 系统调用 的手册页(系统调用不是 system(3 ) 分叉 shell 的函数)。

详细了解系统调用Linux 内核,以及操作系统<的整体组织< /a>

回到你的问题,您可以引用 shell(只需遵循 shell 转义规则来转换您的字符串;例如,在任何非字母字符前加上反斜杠)。

另请参阅 forkexecve 等。

阅读一本关于 高级Linux编程和著名的高级 Unix 编程

使用 Linux 发行版上大多数软件的自由度。例如,您可以研究像 sash 这样的简单 shell 的源代码。

也许您只想使用curl。那么最好的方法是libcurl库编写代码(无需任何调用到 system(3))

祝学习这一切愉快!

See the man page listing all syscalls (system calls are not the system(3) function which forks a shell).

Read more about system calls and linux kernel, and the overall organization of operating systems

Back to your question, you could quote for the shell (just follow the shell escape rules to transform your strings; for example prefix any non-letter character with a backslash).

See also the man pages of fork, execve, etc.

Read a good book on advanced linux programming and the famous Advanced Unix Programming

Use the freedom of most of the software on a Linux distribution. For example, you could study the source code of a simple shell like sash.

And perhaps you just want to use curl. Then the best way is to code for the libcurl library (without any call to system(3))

Have fun learning all this!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文