#!/usr/bin/env bash
?This business of using #!/usr/bin/env whatever is getting out of hand.
It was originally suggested as a fix for a specific problem, but somehow it’s morphed into a general purpose “portability” fix. And worse, it’s started being promoted as “best practice” in some circles, when it’s anything but.
There is a widespread myth that it is more “portable” than #!/path/to/whatever, and that portability is all that matters.
Both of those are wrong.
In some cases it’s simply not more portable; in particular /bin/sh
is more
widely available than /usr/bin/env
(which, contrary to this myth, is not
available “everywhere”).
Footnote: some systems dispense with having
/bin
and instead install everything in/usr/bin
, but since they have a symlink from/usr/bin
to/bin
, that means that/bin/sh
is still valid. Other systems have neither/bin
nor/usr/bin
, having instead/system/bin
, so again you’re no worse off by using/bin/sh
.The nexus of the security vulnerability is that using
#!/usr/bin/env
ensures that the script itself is unable to sanitize the environment before relying upon it.
It is often suggested that #!/usr/bin/env whatever is harmless even when it provides no benefit.
In any given instance that may be true, but not always. The greater harm is in
normalizing it and using it unthinkingly everywhere. This inevitably winds up
with env
being used in circumstances where it creates compatibility problems
or even security vulnerabilities.
Footnote: The retort that “this doesn’t affect security on its own” is both true and wrong: we have security breaches precisely because of assumptions that things are safe because nothing else stupid has been done. The “best practice” approach to security includes “defence in depth”: many layers of guards and locks, because some of them will inevitably be broken.
The “beneficiaries”, if you can call them that, are the users who are too naïve to edit the shebang line and put the correct path to the interpreter there. Which means they’re also too naïve to assess the security implications of what they’re doing.
The prime use-case for env
was to support systems where the user does not have
the ability to install or replace software at a given path; for example MacOS
locks down /bin/bash
to version 3 which is inadequate for many modern scripts.