/usr/bin/env 作为一个 shebang - 及其安全含义

/usr/bin/env 作为一个 shebang - 及其安全含义

我在几个地方看到了使用以下 shebang 行的建议

#!/usr/bin/env bash

代替

#!/usr/bin/bash

我下意识的反应是,“如果有人用这个可执行文件替换他们自己的可执行文件怎么办~/.local/bin?”该目录通常设置在系统范围路径之前的用户路径中。我认为这是一个安全问题,通常作为旁注而不是任何值得认真对待的问题,但我想测试这个理论。

为了尝试这个我做了这样的事情:

echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/bash
chmod 755 $HOME/.local/bin/bash
PATH=$HOME/.local/bin env bash

这产生

/usr/bin/env: ‘bash’: No such file or directory

为了检查它是否拾取了任何东西,我也做了

echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/perl
chmod 755 $HOME/.local/bin/perl
PATH=$HOME/.local/bin env perl

正如我所料,它打印出

Hacked!

有人可以向我解释为什么bash没有找到替代品,但找到了替代品perl吗?这是某种“安全”措施(从我的角度来看)没有抓住要点吗?

编辑:因为有人提示我:我不是问/usr/bin/env bash与使用有何不同/bin/bash。我正在问如上所述的问题。

EDIT2:这一定是我做错了什么。今天再次尝试(使用显式路径env而不是隐式路径),没有出现这种“未找到”行为。

答案1

“如果有人用 ~/.local/bin 中的这个可执行文件替换自己的可执行文件怎么办?

那么这个脚本对他们就不起作用了。

但这并不重要,因为他们可以通过其他方式自行破坏脚本,或者直接运行另一个程序而不会弄乱PATHenv

除非你的用户有其他用户的目录PATH,或者可以编辑PATH其他用户的目录,实际上不可能一个用户弄乱另一个用户。


但是,如果它不是 shell 脚本,而是授予额外权限的脚本,例如某些程序的 setuid 包装器,那么情况就会有所不同。在那种情况下,那就是必要的使用绝对路径运行程序,请将其放置在非特权用户无法修改的目录中,并在启动程序时清理环境。

答案2

至于 shell 和 之间的行为差​​异perlperl与 shell 检查第一行以确定要运行的内容不同:

$ cat tcl
#!/usr/bin/env tclsh
puts "TCL running as [pid]"
$ perl tcl
TCL running as 39689
$ cat sbcl
#!/opt/local/bin/sbcl --script
(format t "~a running as ~a~%" 'lisp (sb-unix:unix-getpid))
$ perl sbcl
LISP running as 39766
$ 

此功能的用途包括用 Perl 之外的其他语言编写测试因此,人们可以使用其他语言编写与 TAP 兼容的脚本,并且prove可以正确运行它们。

答案3

这里没有安全风险。/usr/bin/env应该根据用户的环境选择合适的二进制文件。因此,如果用户bash在 中安装了自己的~/.local/bin版本,那么/usr/bin/env确实应该尝试使用它(例如,他们可能编译了一个具有系统范围版本中不可用的额外功能的版本,并且更愿意在系统范围版本的位置)。对于任何其他二进制/解释器也是如此。不存在安全风险,因为用户将无法运行任何他们本来无法运行的内容。

至于为什么替代品在你的情况下失败,我怀疑它与/usr/bin/env.尝试运行PATH=~/.local/bin bashPATH=~/.local/bin bash <path-to-script>运行脚本时会调用它)并PATH=~/.local/bin /usr/bin/env bash查看哪些失败。这应该可以提供有关“找不到文件”错误所指的线索。

相关内容