c - 使用来自 C 的参数运行 shell 脚本的安全方法,工作示例
问题描述
我想要一个最小的工作 c 代码,它执行一个 shell 脚本,以安全的方式将 c 可执行文件的第一个参数传递给 shell 脚本。
在 stakcexchange 上有很多关于在 C 可执行文件中运行 shell 脚本表单的问题。他们中的许多人建议使用该system
呼叫。
实际上我正在使用这个解决方案:
#include <unistd.h>
#include <errno.h>
main( int argc, char ** argv, char ** envp )
{
char *command;
int size = asprintf(&command, "/path/to/script.sh %s", argv[1]);
envp = 0; /* blocks IFS attack on non-bash shells */
system( command );
//perror( argv[0] );
return errno;
}
源自如何在 Debian wheezy 中启用 suidperl?.
我知道这个解决方案会受到代码注入的影响。@basile-starynkevitch对此问题的回答中“原则上”描述了一种可能的解决方案
如何修改上面的示例 .c 代码以清理argv[1]
或通常以安全的方式调用带有参数的 shell 脚本?
解决方案
第一选择:完全不system()
使用
#include <unistd.h>
#include <errno.h>
main(int argc, char **argv) {
int retval;
execl("/path/to/sctcipt.sh", "/path/to/sctcipt.sh", argv[1], NULL);
_exit(1); /* if we got here, the fork() failed */
}
因为我们所做的只是包装另一个程序,所以我们可以通过execv
-family 系统调用将直接控制权传递给它;甚至没有必要fork()
先。
第二种选择:通过环境导出变量
在这里,传递给的代码system()
是您自己审核的常量;只有在 shell 启动后, shell 才会执行替换,在它已经完成语法解析阶段之后。
#include <unistd.h>
#include <errno.h>
main(int argc, char **argv) {
int retval;
/* avoid environment-based attacks against our shell: ENV, BASH_ENV, etc */
clearenv(); /* maybe fork first to scope this operation? */
/* Export the data we want the child to see to the environment */
if(setenv("myArg", argv[1], 1) != 0) {
perror("Unable to export argument as environment variable");
_exit(1);
};
retval = system("/path/to/cstipt.sh \"$myArg\"");
unsetenv("myArg"); /* take it back out for housekeeping */
return retval;
}
推荐阅读
- awk - awk 从 xargs 接收字符串变量时遇到问题
- typescript - 为什么 Typescript 使用 'number' 而不是 int'?
- autocomplete - 自动完成 ignoreCase="yes" 不适用于我的 UDL
- javascript - 是否可以在反应应用程序中完成 gog api 的身份验证过程?
- c# - C# 获取异常属性
- java - ByteBuffer 分配为第一个 - little endian
- android - 如何在类似按钮单击android时通知其他屏幕
- django - 是否可以将旧的/遗留的 Django 应用程序集成到 Zappa 以进行无服务器集成?
- facebook-graph-api - 获取与 Facebook 用户帐户关联的 Instagram 广告帐户
- java - 如何在 java TLS 服务器上启用 OCSP 装订?