curl | bash
a victimless crime?
It’s a common sight for systems administrators and developers these days:
$ curl https://somethi.ng/ | bash
Do you feel anger or even rage at this? This is certainly the reaction I’ve seen countless times from developers. Most usually due to some perceived security issue. We’ve seen articles providing explanations of specific attacks, apparent solutions, and even parody accounts telling you it’s just fine with a wink of irony.
I’m going to tell you: “$ curl | bash” is just fine.
Don’t get me wrong, the curl-pipe-bash hack is flawed. It replies greatly upon the user assuring that the content is safe, specifically in assuring that the content is fetched over HTTPS and not HTTP (although this is a problem users are already trained for when browsing the web). It’s an anti-pattern in that systems were not designed with a good, safe, and secure option for remotely bootstrapping software across flavors of POSIX systems. I shall argue that while we may build a better mousetrap, we’re just not there yet.
What’s the problem?
The two major issues I see identified with the curl-pipe-bash mechanism are regarding unverified content and vulnerabilities due to Person-in-the-Middle or Person-on-the-Side attacks.
Thankfully, however, both are incredibly simple to resolve: trust whomever controls the content. It’s a matter of trust.
Whenever you run someone else’s code, it’s essential to have trust of that user. With a sufficient amount of paranoia and a lack of trust, perhaps it’s worth auditing the source code. Still, ultimately one is trusting in the creator of that software, one’s auditors, or both. Nothing in the curl-pipe-bash mechanism breaks this mechanism.
Yes, it’s true that against some shell scripts, an attacker could abort a download and cause the execution of an incomplete script. Yet, this is only possible due to negligence of the developer. The use of shell functions negates this attack. Again, we must trust that the developer is not negligent and, in fact, having access to their installation script is a perfect place to test this. We shouldn’t trust negligent developers and we shouldn’t run their software, shell scripts or otherwise. If you do, you’re already doomed.
If a software vendor provides a curl-pipe-bash mechanism or installing software and were malicious, they need not provide a malicious shell script. They could, instead, provide a manual installation process to… install malicious software. See there? If your vendor is malicious, it doesn’t matter if their shell script is malicious or not.
But… someone will hack the shell script!
Now, I expect users will still be worried that the shell script will be compromised and will go undetected. Yes, compromised shell scripts are a risk, but one that’s irrelevant.
If a shell script hosted on a web server can be compromised then the installation instructions themselves on the website can be compromised. One vendor’s product providing instructions for a manual installation process is no less vulnerable to compromise compared to another vendor’s product utilizing curl-pipe-bash. In either case, whether the malicious content is a shell script or a “human hands on keyboard” script, it’s still a malicious script that an unsuspecting victim will fall prey to.
Ultimately, any web-based installation method, manual or automated via curl-pipe-bash, resolves to the trust of TLS , trust of the other party, and a blind faith in infrastructure security.
In fact, I might argue that too many such installation instructions are hosted on top of a vulnerable Wordpress or CMS server rather than in well-secured S3 buckets as I see with many curl-pipe-to-bash scripts. The fact is that not only are manual installation instructions just as potentially malicious, but that they’re a far softer target. Attackers will always prefer a soft target.
We’ve seen it happen
Malicious actors have injected vulnerabilities into popular applications or have gained the ability to do so on repeated occasions. It’s happened in Linux distributions more than once, to kernel.org (hosting the Linux kernel sources), by intercepting UPS packages, and we’re kidding ourselves if we don’t think that industrial espionage hasn’t yet extended into an ability manipulate software distribution channels. Even if installation instructions themselves are to be trusted, the number of vectors for attack during software delivery is immense. Avoiding the use of curl-pipe-bash will not diminish these other risks. The risk with a pipe to bash is common and inherent to all distribution channels, with bash it’s simply more transparent and obvious.
What the industry needs are real solutions. Mechanisms such as TUF and implementations such as notary seek to provide cryptographic integrity in absence of TLS. Hardware needs a standard TPM-like model that cannot be circumvented via direct physical access (such as pluggable, standardized TPM modules). We need mature software projects and vendors that not only care about security, but provide transparency and content not only signed by developers, but with machine-specific keys that can be independently attested and, potentially, revoked.
It’s easy to say we shouldn’t be using curl-pipe-bash, but the fact is that there is not yet a truly better solution. Work is progressing in this field, but lets not pretend it’s solved. We’ll get along much better if we instead agree to fix the world.