Curl to shell isn’t so bad
Written on 9 Nov 2019 − last updated on 24 Nov 2019 history
Discussions: Lobsters, Hacker News, /r/commandline.
Piping curl to s(hell) claims that using curl example.com/install.sh |
sh
to install software is a “glaring security vulnerability”. I’ve seen this
claim many times in other places as well, with strong terms like “malpractice”.
I don’t get it. You’re not running some random shell script from a random author, you’re running it from a software vendor who you already trust to run software. Are you going to audit all of oh-my-zsh? Probably not. So why give extra gravity to their install script? If you trust oh-my-zsh then there’s no reason to distrust their install script.
There is no fundamental difference between curl .. | sh
versus cloning a repo
and building it from source. Do you know what’s in any of that autoconf soup?
Even the source m4 is often hard to understand, and the generated configure
scripts are tens of thousands of lines of unreadable autogenerated code. No one
audits that and it’s the perfect place to hide nefarious commands.
It’s worth pointing out that the install scripts for all the cited examples are
in source control[1] and subjected to the same kind of auditing as the
software itself. There is no hard guarantee that the file in git is the same as
the one you download from https://sh.rustup.rs
, but you also have no
guarantees that https://rust-lang.org/rust-1.39.tar.gz
is really the same as
git, and I don’t see anyone calling this a “glaring security vulnerability” or
“malpractice”.
Package managers are more secure due to checksums, signing, and
auditing.[2] You should use a package if available (often it’s not, hence
these scripts). curl | sh
is certainly not a perfectly secure method, just
no different than git clone && cd dir && make
, and I don’t see anyone issue
warnings against that.
The only real security difference I see is that curl | sh
is a very direct
way to run code from the internet, whereas the other methods are running code
from the internet, but with extra steps. It may “feel” different, but in reality
it’s just the same. In the end it’s still just running code you didn’t
personally audit on your computer, and a matter of trust.
To break down the bullet points in the article in some more detail:
-
Man-in-the-middle attacks: this is only a problem “if the developers omit the usage of TLS”, as the article already mentions. This is increasingly rare, and all of the cited examples use TLS.
I’ll also add that MITM attacks are usually not very practical, and almost a non-issue for things like this. The practicalities of actually doing this sort of thing just don’t work out.
-
Hidden text attacks: it’s possible to trick browsers in copying “hidden” text with some HTML and CSS trickery. This is known as “pastejacking”.
If I trust docker.com enough to run
dockerd
, then why shouldn’t I trust their website to not inject hidden stuff?People are going to paste stuff in their terminals regardless (keys, passwords, code snippets, what have you) so this is best fixed in the terminal or shell instead of telling people to “not do that really convenient thing”. zsh has been doing this by default for years; and it looks like newer versions of bash do too.
As far as I’ve been able to find, there has never been any real-world attack using this technique, so it almost becomes a philosophical question: “if there is a potential security problem and no one is exploiting it, then is it still a security problem?”
-
User-Agent based attacks: a server can send a different version to Firefox than curl.
As with the previous issue: you’re already trusting the vendor and site, and you’re already going to run the software that
install.sh
downloads. No need for these kind of tricks. -
Partial content: the shell may execute half the script due to a network error.
Easily fixable by running in a function:
do_work() { : } do_work
All of the cited examples already do this.
-
Not knowing what the script is going to do.
I tend to avoid these kind of scripts for exactly this reason, but this is a personal preference and not a security issue. (For reasons I don’t fully understand myself I am somewhat irrationally obsessed with keeping my system as “light” as possible, almost to the point of stupid light.)
It’s fine to not like these scripts, but that doesn’t make them “glaring security vulnerability” or “malpractice”.
- The problems with piping curl to a shell are system management ones – I mostly agree with Chris; “trust” in the sense “doesn’t do anything malicious” is probably a safe bet, but “trust” in the sense “trust this script won’t do anything to my system that I would rather not have” is more tricky; where will it download stuff? Which files and directories are created? Can I easily undo whatever it does? How well does it deal with failure like some shell utility not being present? These are serious concerns, but different ones from security concerns.