是否可以在运行脚本时显式更改 shell 脚本(bash 脚本)的 $0 参数?
考虑以下脚本:
readonly SCRIPT_HELP="$(cat <<EOF
Usage: $(basename "$0") [-h]
EOF
)"
echo "${SCRIPT_HELP}"
是否可以将其他内容作为参数 0 传递给此 bash 脚本,以便$(basename...
使用某些用户提供的代码执行评估(可能有害)?
一般来说,是否可以利用参数 0 在特定 shell 脚本中未正确清理的事实?
答案1
$0
可以是脚本调用者想要的任何内容。这是脚本的路径,调用者可以在任何位置复制或链接到该脚本。
然而,这本身并不是一个漏洞,除非脚本以比其调用者更多的权限运行。除非脚本可执行文件具有特权,否则调用者可以运行不同的程序。如果调用者本身具有特权并且可以被说服传递不同的$0
.
如果脚本以特权运行,那么具体情况$0
取决于用于提升特权的方法。如果通过指向 setuid 可执行文件的符号链接调用脚本,那么脚本$0
可能是任意的(但是大多数系统拒绝 setuid 可执行文件)。
尽管在这种特殊情况下的大多数情况下缺乏安全隐患,您的脚本对于任意$0
.双引号导致"$0"
值按原样使用(而不加引号$0
则将其视为通配符模式列表)。但是,当basename
命令将该值视为参数时,它会根据该值是否以 开头来进行不同的处理-
。如果该值以 a 开头-
(并且不仅仅是-
),那么它是一个选项。至少对于 GNU 来说basename
,非选项参数是强制性的,因此使用以 开头的单个参数调用它-
只会导致错误。但对于其他一些命令来说,这是一个更大的问题。为了处理任意值,包括以 开头的值-
,请放在--
参数之前以指示后面没有更多选项:basename -- "$0"
。
答案2
决定$0
应该是什么是微不足道的。只需创建一个链接:
$ cat foo.sh
#! /bin/bash
readonly SCRIPT_HELP="$(cat <<EOF
Usage: $(basename "$0") [-h]
EOF
)"
echo "${SCRIPT_HELP}"
$ ./foo.sh
Usage: foo.sh [-h]
EOF
$ ln -s foo.sh bar.sh
$ ./bar.sh
Usage: bar.sh [-h]
EOF
在这种特殊情况下,不,我不认为可以利用它来获得任何巨大的优势。"$0"
和SCRIPT_HELP
在使用时被引用(在嵌套命令替换和此处文档中,但仍然被引用),并且它们没有被eval
编辑。
$ ln -s ./foo.sh '"; echo rm -rf ~; echo"'
$ ./\"\;\ echo\ rm\ -rf\ \~\;\ echo\"
Usage: "; echo rm -rf ~; echo" [-h]
EOF