`curl https://somesite.com/foo.sh | bash`
with
`curl https://somesite.com/foo.deb`
and
`curl https://somesite.com/apt.key | sudo apt-key add - && sudo apt-get update && sudo apt-get install some-software`
I don't think there are very meaningful differences in the security properties -- I don't think it's more difficult to become compromised by one than by one of the others.
But I agree with your sentiment. If the exact same step was to `apt install ecs-cli` I would just do that and not feel any inconvenience about it.
https://joeyh.name/code/moreutils/ https://rentes.github.io/unix/utilities/2015/07/27/moreutils...
Be very careful here. https://installation.s3.amazonaws.com/setup.sh looks like a legit URL, but it's just some guy with an S3 bucket named "installation".
Say you already trust the website you're downloading from, is there an increased security risk doing curl | bash as compared to rpm --import https://example.com/RPM-GPG-EXAMPLE && yum install https://example.com/example.rpm
No matter what you're putting 100% faith in the the server and the TLS connection. There are a lot of reasons to prefer packages, but I don't think security is one of them.
I think there's a difference between trusting an organization's code that is published to the general public, and trusting an organization to send you arbitrary code in a specific moment. Only software distribution methods can enforce this kind of distinction, and curl | bash by itself doesn't, particularly in light of the article's technique.
I tried to discuss this distinction in some of my reproducible builds talks. There's a difference between trusting Debian to publish safe OS packages, and trusting Debian to send you a safe package when you run a package manager if the package could easily be different every time. This is particularly so when someone may be able to compromise the software publisher's infrastructure, or when a government may be able to compel the software publisher to attack one user but other users.
Instead of your (1) and (2) above, how about this?
1) Distributing software via a method that can single out particular users and groups to receive distinctive versions is a bad idea: it increases the chance that some users will actually be attacked via the software publication system.
2) We might think that curl | bash isn't particularly egregious this way, because there are various ways that publishers might get caught selectively providing malicious versions. This is especially so because the publishers can't tell whether a curl connection is going to run the installer or simply save it to disk. That makes the publishers (or other people who could cause this attack to happen) less likely to do it.
3) But haha! Here is a clever trick that restores the publishers' ability to distinguish between running and saving the installer, and in turn breaks the most plausible ways that publishers could get caught doing this.
Edit: Elsewhere in this thread you suggested that the likeliest alternative is something like
curl https://somesite.com/apt.key | sudo apt-key add - && sudo apt-get update && sudo apt-get install some-software
I think I'd agree that this has some of the same problems, although it might have some advantages because of the potential decoupling between the distribution of the signing key and the distribution of the signed package. As another commenter pointed out, you could try to use a different channel to get or verify the key, and some users actually do; also, you'll have a saved copy of the key afterward.
A=$(curl -L https://get.rvm.io);echo "$A" | shasum -a 256 | grep -q 05b6b5f164d4df5aa593f9f925806fc1f48c4517daeeb5da66ee49e8562069e1 && (echo "$A")
You shouldn't, but people do, and are being directed to do so increasingly as Linux becomes more popular. Software developers want to be software publishers so bad that they're just going to keep pushing, and therein lies the risk: If people get the impression that packages are somehow more secure than shell scripts, then these kinds of attacks will simply become more prevalent.
To you it's obvious that packages aren't more secure, it's how you get them that makes their normal use more secure. That's apparently too subtle a point for even big companies like Microsoft.
https://pydio.com/en/docs/v8/ed-debianubuntu-systems
https://docs.docker.com/install/linux/docker-ce/ubuntu/#inst...
https://www.spotify.com/uk/download/linux/
https://www.elastic.co/guide/en/apm/server/current/setup-rep...
https://ring.cx/en/download/gnu-linux
http://docs.grafana.org/installation/debian/
https://support.plex.tv/articles/235974187-enable-repository...
https://stack-of-tasks.github.io/pinocchio/download.html
http://download.mantidproject.org/ubuntu.html
https://docs.microsoft.com/en-us/cli/azure/install-azure-cli... (!!!)
Really? Are they going to read every line of code and every line of code in every dependency that the install script installs?
The bash detection is clever but I think its a solution to a problem that doesn't exist.. Its already very easy to install hide malicious code in plain sight, why go to all this trouble to detect if the user is piping to bash?
For example, see how easy it is to publish a fake npm package or a .deb package:
https://hackernoon.com/im-harvesting-credit-card-numbers-and...
I wrote a tool that could be used like that but it's useless if its not ubiquitous (https://github.com/mmikulicic/runck)
$ curl <url> | pipe-checksum <expected> | bash
https://gist.github.com/pcl/64bd2f56695fcf8e1fad51443aab1f1eEg the key from https://docs.docker.com/install/linux/docker-ce/ubuntu/#set-... doesn't have signatures, and isn't on the keyservers.
Of course an unsigned key missing from the keyservers still has the advantage that on subsequent installs/updates, the previously downloaded key persists. And you can keep the initially downloaded key in your CI configs.
This is ... not everything that it could be, and is approaching 30 years old, technology built for a vastly different world.
But this is the basis of the GPG / PGP Web of Trust.
https://en.wikipedia.org/wiki/Web_of_trust
http://www.pgpi.org/doc/pgpintro/
http://www.rubin.ch/pgp/weboftrust.en.html
(I've addressed this point ... a distressing number of times on HN: https://hn.algolia.com/?query=dredmorbius%20web%20of%20trust... 0
At any rate - code-signing doesn't really help if the author is the attacker.
Indeed. While this particular venue wouldn't have worked for:
https://wiki.gentoo.org/wiki/Project:Infrastructure/Incident...
(a compromise of github itself would be needed) - it's easy to imagine one of the many mirrors of Debian to suffer from compromise. But as they just push signed debs, the damage would be limited (not trivial, there could conceivably be bugs in apt/dpkg/gnupg etc).
curl -s \
'https://pgp.mit.edu/pks/lookup?op=get&search=0x1657198823E52A61'
| gpg --import \
&& if z=$(curl -s 'https://install.zerotier.com/' | gpg);
then echo "$z"
| sudo bash;
fi
It's interesting - it tries to import a given gpg key from keyserver, then grabs a gpg armored text file with a bash header - with the gpg header wrapped in a here-document: #!/bin/bash
<<ENDOFSIGSTART=
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
ENDOFSIGSTART=
I'm unsure, but I think you could just stick your malicious code before the signature? #!/bin/bash
sudo much_evil
<<ENDOFSIGSTART=
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
ENDOFSIGSTART=
So it really isn't any better, as far as I can tell. There's also a trade-off between scripts that can be typed (curl https://i.com.com) and need copy-pasting - as copy-pasting also isn't safe - even if that's a somewhat different attack vector (compromising the web site, altering js depending on visitor).When RPM-GPG-EXAMPLE and example.rpm are both coming from https://example.com it's less clear. When example.com is coming from a mirror repository, or being emailed around (yes, this happens), package signing asserts that example.rpm was signed by the signatures in RPM-GPG-EXAMPLE, which has a strong (but not bullet-proof) connection as being built by example.com.
From that example, we can see that package signing also protects from someone who's able to break into the main example.com webserver but not example.com's build system - if the attackers did not get into the build system and example.rpm has a valid signature then despite the webserver being broken, the rpm file can still be trusted, assuming the webserver did not have a copy of the private key used for build signing. If we loaded https://example.com/RPM-GPG-EXAMPLE before the webserver was broken into, and then the webserver was broken into and a malicious RPM-GPG-EXAMPLE and example.rpm were uploaded, it would be noticed. (Examining changes to RPM-GPG-EXAMPLE are, unfortunately, left to the reader as an exercise.)
Still, while it's true that loading the file from https://example.com/RPM-GPG-EXAMPLE relies on TLS, but there are methods available to confirm that the file's contents are valid, that don't rely on TLS, if the security folk at example.com are doing their job.
Finally, TLS is not an all or nothing game. Or rather, the certificate used to sign the https connection does not have to be blindly trusted, and in the case of sketchy root certificates, even if https://example.com loads fine in a web browser, it does not mean it should necessarily be trusted. Certificate Transparency (eg crt.sh) is a proper lever when working with example.com.
Security is complicated and there are no silver bullets.
`curl | sudo bash` is batshit though.
The code starts to send chunked data and polls for a return curl call from the downloaded script. If the script's curl call calls home, the download will chunk out "bad" bash.
What I see happening is the downloaded script does not fully run until fully downloaded.