有没有一种方法可以防止 sh/bash 执行命令替换?

4

我想从一个C程序中调用一个带有文件名参数的shell脚本。用户可以控制文件名。C代码如下(初始化/错误检查已省略):

sprintf(buf, "/bin/sh script.sh \"%s\"", filename);
system(buf);

目标设备实际上是一个嵌入式系统,因此我不需要担心恶意用户。显然,在Web环境中,这将成为攻击向量。但是,如果系统上有一个文件名,例如包含反引号的名称,则命令将失败,因为shell将对名称执行扩展。有没有办法防止命令替换?


1
使用单引号 ' 代替双引号 "。Bash 不会进行替换。例如:sprintf(buf, "/bin/sh script.sh '%s'", filename);。然后一切都取决于 script.sh 在做什么。您可能还想为受限 shell 指定 -r,但在这种 shell 中有一些限制,有关更多详细信息,请参阅 bash 手册页中的“受限 shell”部分。 - user405725
4个回答

3

0
尝试在系统函数中触发“unalias”命令。

0

由于您标记为 C,我将为您提供 C 的答案。 您需要转义文件名 - 创建一个新字符串,该字符串将由 shell 正确处理,使得像 This is a file name 产生 This\ is\ a\ file\ name 或者 bad;rm *;filename 变成 bad\;rm\ \*\;filename。然后您可以将其传递给 shell。

绕过这个问题的另一种方法是使用 fork 和其中一个 exec 函数直接运行 shell。 直接将参数传递给程序不会导致 shell 命令行扩展或解释。


0
如sharth所说,您不应该使用system,而是应该自己使用forkexecv。但是为了回答如何使字符串安全地传递给shell的问题(如果您坚持使用system),您需要转义字符串。最简单的方法是首先将每个'(单引号)替换为'\''(单引号,反斜杠,单引号,单引号),然后在字符串开头和结尾添加'(单引号)。另一种相当简单(但通常不太有效)的方法是在每个字符前面放置一个反斜杠,但是然后您仍然需要做一些特殊的引号技巧来处理嵌入式换行符,因此我更喜欢第一种方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接