已关闭。此问题需要更多focused。当前不接受答案。
**想要改进此问题吗?**更新问题,使其仅关注editing this post的一个问题。
三年前就关门了。
Improve this question
我们正在编写一个接收参数的Linux bash shell脚本。我们希望在脚本接收可能的shell注入命令作为参数时使脚本失败。我在下面使用regex添加了一些命令。有人能给予我所有此类命令的可能列表吗?这样我们就可以避免威胁
invalid_format="(^.*[;&|].*$)|(\brmdir\b)|(\bls\b)|(rm\s-)|(\bping\b)"
if [[ $LOCAL_DIR =~ $invalid_format ]]; then
echo "Error! LOCAL_DIR cannot contain command chaining characters like ; && || or possible shell injection commands"
exit 1
1条答案
按热度按时间0sgqnhkj1#
不要使用黑名单。
在你的数据中明确禁止的内容的阻止列表只是邀请某人想出一个不在上面的漏洞,或者混淆他们的代码,使正则表达式无法匹配它,或者找到一个古怪的语法,你的 * 实际 * shell 支持,但阻止列表/验证程序是为之编写的。
不要打那必败之仗;相反,编写安全的代码 * 无论数据包含什么内容 *,永远不要将数据注入到可以作为代码计算和执行的上下文中。
在Shell脚本中安全使用参数
*这本身就不安全:
在所有这些情况下,用户提供的值(
$1
)都在一个上下文中使用,在该上下文中它将被shell解析为代码。在所有这些情况下,一个值因此可以运行任意命令。*这永远是安全的
即使在
$1
中有类似$(rm -rf ~)\'$(rm -rf ~\)'
的内容,shell也不会将这些内容作为语法来计算,因此这些值本质上无法作为代码来解析。安全生成Shell命令行
如果强制使用
system()
或某些等效项*这本身就不安全:
*这是固有的安全:
请注意,我们根本没有将值放在传递给shell的字符串中,而是在带外将其传递到环境变量中(使用小写名称,因此它无法覆盖任何对操作系统和支持工具具有安全敏感意义的环境变量)。
从其他Shell脚本生成安全命令行
假设您需要通过SSH运行一个带有不可信输入的命令。
printf %q
可以帮助您:为什么选择
bash -s
?为了确保bash能够解析您的args_str
,因为printf %q
不保证POSIX安全输出。但更好的选择是不调用额外的Shell。
不要使用
system()
或任何调用sh -c
的方法,而是使用直接使用execve()
系统调用的语言级工具来调用脚本。例如,在Python中:不要做其他不安全的事情
{}
,替换了一个被sh
解析为代码的值,所以它被解析为代码,而不是数据,不要这样做。相反,请在带外传递数据:
xargs -d $'\n' sh -c 'for arg; do something_with "$arg"; done' _
(如果您的数据本来就不能包含换行符;如果不能证明这是真的,请使用NUL分隔符和xargs -0
)。find . -type f -exec sh -c 'something_with {}' \;
--与上述xargs
相同的问题,使用相同的解决方案:find . -exec sh -c 'for arg; do something_with "$arg"; done' _ {} +
eval
、source
或其他任何解析非常数字符串的代码。您根本不应该 * 在代码中 * 使用它们。ls
。不要用换行符分隔文件名--用NULL代替。