Comment by Skunkleton
8 hours ago
I've never understood the security argument people are making when they complain about `curl foo | bash`. I get that these scripts sometimes mess up your bashrc or whatever, but from a security perspective I see no issue. You are already installing software from the same domain. If they were going to do something nasty, they could do it with any of the software you are using from them. It doesn't have to be the setup script.
To compare it to just one other option: when you run `npx foo`, you know* that you’re getting the same public artifact that anyone else running it at the same time would get. (If you have a `min-release-age` configured, you also benefit from that.) If I wanted to distribute software like this, I’d include npm-shrinkwrap.json; then, with `npx foo@1.2.3`, you could be similarly confident in getting the same app every time.
(I picked this option for ease of comparison, getting a couple of major security wins with very low effort; I don’t recommend `npx`ing stuff in an otherwise unprotected environment either.)
* well, you can be somewhat more sure
So to be clear; the solution is then something like
`curl https://raw.githubusercontent.com/my/domain/setup.sh | sh`
Note we dont even have a hash there - just a promise that a third party (github) has a log of whatever was hosted at that url.
maybe then we'll pin hashes instead of filenames, and oops now anybody can fork my/domain and hand out a link that looks official with whatever contents they wish
While I don't think piping curl into bash is the most secure, npm installing has proven time and time again to open yourself up to supply chain attacks. At least with curl you know that you're getting the supply chain put together by the software author. With npm, every single library is a vector for attack every time you update.
You’d be getting the supply chain put together by the software author in either case. It’s common to do both badly, but if you care about doing it well, that’s easier with npm (e.g. shrinkwrap, as mentioned) and can be taken farther (the non-varying artifact thing).
2 replies →
You can detect the use of curl|bash server side, hence it's an essentially undetectable attack vector. People have shown poc attacks of that kind all the way back in the 2010s
https://news.ycombinator.com/item?id=17636032
The original blog is no longer available though.
But I've not had that stop me from doing that myself, I am more towards the "I like easy" then the "I want to be secure" crowd
There’s a snapshot on web archive:
https://web.archive.org/web/20250109045029/https://www.idont...
How would you do that? Just rely on the user agent? I use curl quite a lot, but don't pipe to a shell.
The setup script often runs privileged (by calling sudo) and that's not unexpected when installing new software.
When I install something, and it asks for my root password later, I will be much more likely to think "hold up, this ain't right".
(this is not an endorsement of curl | sh, just an indictment of the state of software)
when people left their laptops unlocked, we used to wrap their sudo so that the output would be pre- and postfixed with ascii dolphins
Can you give me a popular example that requires sudo? I don't think that is very common at all.
every single bash replacement for one.
oh my zsh is a specific example.
chsh requires sudo on most installs.
People with less experience normalize that behaviour and when the domain is not trusted the habit let their guard down. See all the clickfix attacks.
The intended workflow is to download the install scripts, download the source code, read them both, and then start running things. That’s how Open Source is secured. Piping from bash to curl is just the most obvious warning flag.
And practically zero people are actually using this "intended workflow" in the real world.
Yes, the status quo is quite bad, which is why it gets complained about a lot.
I push binaries from untrusted sources through VirusTotal before running them. Piping a Bash script from curl bypasses that. Furthermore, such Bash scripts, when they aren’t self-contained, make security checks more difficult than a self-contained archive, installer, or binary, even when downloading the script without immediate execution.
You could always curl the install script, and modify it to run the virus scan in between the build and install steps.
Nothing is stopping anyone from pointing their agent to that script to review and audit it before running it.
I don’t believe an agent can do that effectively without a sandbox to run the script in, if the script isn’t self-contained.
And everyone running a research agent on every download can’t be the solution. It’s much more effective to crowdsource a security database based on hashes. But for that, the downloads need to be self-contained.
It's `curl foo | sudo bash` that's the bigger objection. Running software usually shouldn't require root, and then the equivalence argument you make doesn't hold.
a script isn't getting hashed to see whether or not it's the one the website intended to serve you, for one.
what use is hashing every piece of software that goes thru the distros package manager just to throw caution to the wind at the layer above it?
w.r.t. "it's already from the same domain" , well most bash/z install scripts either invoke a package manager or they download and untar a package that has nothing to do with the host domain, anyway.
The real problem is that we just aren't using package managers. We should be using package managers. Package managers are really really good.
There is no argument. It's just people's reflex reactions.
The technical excuses they come up with (e.g. that the server can detect it and send different content) are just post-hoc justifications for their instinct.
Just ignore them.