I at least skim all the scripts I download this way before I run them. There's just all kinds of reasons to, ranging all the way from the "is this malicious" to "does this have options they're not telling me about that I want to use".
A particular example is that I really want to know if you're setting up something that integrates with my distro's package manager or just yolo'ing it somewhere into my user's file system, and if so, where.
(Nix isn’t the solution for OP’s problems though – Nix packages are unsigned, so it’s it’s basically backdoor-as-a-service.)
It created users and groups on my system! And the uninstall script didn't clean it up.
Lovely sentiment, not applicable when you actually work on something. You read your compiler/linker, your OS, and all libraries you use? Your windowing system? Your web browser? The myriad utilities you need to get your stuff done? And of course, you've read "Reflections on trusting trust" and disassembled the full output of whatever you compile?
The answer is "you haven't", because most of those are too complex for a single person to actually read and fully comprehend.
So the question becomes, how do you extend trust. What makes a shell script untrustworthy, but the executable you or the script install trustworthy?
This is the "Unofficial Way".
These scripts are often written by people who only know one OS well (if any), and if that OS is macOS, and you're on Linux (or FreeBSD, or whatever), you can expect them to do weird shit like sticking binaries into /usr/bin in circumvention of the package manager, or adding their own package repositories without asking you (and often not whitelisting just their packages, which allows them to e.g. replace glibc on your system without you noticing), etc.
It's not comparable to simply using the already installed software.
Supply-chain attacks. Linux distros have a long history of being more hardened targets than "a static file on some much, much, much smaller project's random server".
Also things like linux packages or snaps or flatpaks are generally somewhat ringfenced by their nature. Here I don't mean for security reasons per se, but just by their nature, I have confidence a flatpak isn't going to start scribbling all over my user directory. A script may make any number of assumptions about what it is OK to do, where things can go, where to put them, what it can install, etc.
"Trust" isn't just about whether something is going to steal my cryptowallet or install a keylogger. It's about whether it breaks my reproducible ops setup, or will stick configuration in the seventeenth place in my system, or assumes other false things about how I want it set up that may cause other problems.
I'll take a script that passes `shellcheck ./script.sh` (or, any other static analysis) first. I don't like fixing other people's bugs in their installation scripts.
After that, it's an extra cherry on top to have everything configurable. Things that aren't configurable go into a container and I can configure as needed from there.
How many times will a novice user follow that pattern until some jerk on discord drops a curl|bash and gets hits
IRC used to be a battlefield for these kinds of tricks and we have legit projects like homebrew training users it’s normal to raw dog arbitrary code direcly into your environment
"Back in the day" we cloned the source code and compiled ourself instead of distributing binaries & install scripts.
But yeah, the problem around curl | bash isn't the delivery method itself, it's the unsafe user behavior that generally comes along with it. It's the *nix equivalent of downloading an untrusted .exe from the net and running it, and there's no technical solution for educating users to be safe.
Safer behavior IMO would be to continue to encourage the use of immutable distros (Fedora silverbue and others). RO /, user apps (mostly) sandboxed, and if you do need to run anything untrusted, it happens inside a distrobox container.
Almost every one contains preinst or postinst scripts that are run as root, and yet I can count on zero hands the number of times I've opened one up first to see what it was actually doing.
At least a curlbash that doesn't prompt me for my password is running as an unprivileged user! /shrug
Flatpak is a nice suggestion but unfortunately it doesn't seem to work nicely for CLIs.
> "Back in the day" we cloned the source code and compiled ourself instead of distributing binaries & install scripts.
Isn't that the same thing with the extra step of downloading a git repo?
Keep in mind that its possible to detect when someone is doing curl | bash and only send the malicious code when curl is being piped, to make it very hard to detect.
and then inspect foo.sh and then (maybe) cat foo.sh | bash
Does that avoid the issue?
The OS usually has guardrails and logging and audits for what is installed but this bypasses it all.
When you look at this from an attackers perspective, it’s heaven.
My mom recently got fooled by a scammer that convinced her to install remote access software. This curl pattern is the exact same vector, and it’s nuts to see it become commonplace
But I bet she didn't install it with curl piped to bash. The point isn't that curl|bash is safe, but that it isn't inherently more dangerous than downloading and running a program.
No, I'm asking what is a safer method when I want to install some code from the internet.
> The OS usually has guardrails and logging and audits for what is installed but this bypasses it all.
Not everything is packaged or up-to-date in the OS
> My mom recently got fooled by a scammer that convinced her to install remote access software.
Remote access software are packaged in distros too.
Then why don't Linux distributions encourage safe behaviour? Why do you still need sudo permissions to install anything on most Linux systems?
> How many times will a novice user follow that pattern until some jerk on discord
I'm not a novice user and I will use this pattern because it's frankly easier and faster, especially when the current distro doesn't have some combination of things installed, or doesn't have certain packages, or...
You don't with Flatpak or rootless containers, that's partially why they're being pushed so much.
They don't rely on setuid for it either
Or download & compile & install to a PREFIX (e.g. ~/.local/pkg/), and use a symlink-manager to install to e.g. ~/local (and set MANPATH accordingly, too). Make sure PATH contains ~/.local/bin, etc. It does not work with Electron apps though. I do "alias foo="cd ... && ./foo".
Not guix :)
One of the coolest things about it.
When I see a package from a repo, I have some level of trust. Same with a single binary from GitHub.
When I see a curl|bash I open it up and look at it. Who knows what the heck is doing. It does not save me any time and in fact is a huge waste of time to wade through random shell scripts which follow a dozen different conventions because shell is ugly.
Yes you could argue an OS package runs scripts too that are even harder to audit but those are versioned and signed and repos have maintainers and all kinds of things that some random http GET will never support.
You don’t care? Cool. Doesn’t mean it’s good or safe or even convenient for me.
It's worse than that. If your distro doesn't have some package, you're encouraged to just add PPA repos and blindly trust those.
Quite a few companies run their own repos as well, and adding their packages is again `sudo add repo; sudo install`
Yes, it's not as egregious as just `curl | bash`, but it's not as far removed from it as you think.
There are and there has been distros that install per user, but at some level something needs to manage the hardware and interfaces to it.
Am I? How am I affecting other users by installing something for myself?
Even Windows has had "Install just for this user or all users?" for decades
There's nothing stopping you from doing what you like in your user space, but similarly it's no-one else's fault if because of a system change your stuff broke (and hence because sysadmins don't want to do more than they need to, managing things globally is what the expect and support).
Operating systems already have standard ways of distributing software to end users. Use it! Sure maybe it takes you a little extra time to do a one off task of adding the ability to build Debian packages, RPM, etc. but at least your software will coexist nicely with everything else. Or if your software is such a prima-donna that it needs its own OS image, package it in a Docker container. But really, just stop trying to reinvent the wheel (literally).
curl https://example.com/install.sh|yy030
or curl https://example.com/install.sh > install.sh
yy030 < install.sh
Another filter, "yy073", turns a list of URLs into a simple web page. For example, curl https://example.com/install.sh|yy030|yy073 > 1.htm
I can then open 1.htm in an HTML reader and select any file for download or processing by any program according to any file associations I choose, somewhat like "urlview".I do not use "fzf" or anything like that. yy030 and yy073 are small static binaries under 50k that compile in about 1 second.
I also have a tiny script that downloads a URL received on stdin. For example, to download the third URL from install.sh to 1.tgz
yy030 < install.sh|sed -n 3p|ftp0 1.tgz
"ftp" means the client is tnftp"0" means stdin
Given the jungle that is the Linux ecosystem, that bash script is doing an awful lot of compatibility verification and alternatives selection to stand up the tool on your machine. And if what you mean is "I'd rather they hand me the binary blob and I just hook it up based on a manifest they also provided..." Most people do not want to do that level of configuration, not when there are two OS ecosystems out there that Just Work. They understandably want their Linux distro to Just Work too.
(1) feasible traditionally. Projects like snap and flatpak take a page from the success Docker has had and bundle the executable with its dependencies so it no longer has to worry about what special snowflake your "home" distro is, it's carrying all the audio / system / whatever dependencies it relies upon with it. Mostly. And at the cost of having all these redundant tech stacks resident on disk and in memory and only consolidateable if two packages are children of the same parent image.
I call it the worst because it doesn't support installing specific versions of libraries, doesn't support downgrading, etc. It's basically hostile and forces you to constantly upgrade everything, which invariably leads to breaking a dependency and wasting time fixing that.
These days I mostly use devbox / nix at the global level and mise (asdf compatible) at the project level.
I don't like homebrew because I've been burnt multiple times because it often auto-updates when you least want it to and breaks project dependencies.
And there's no way to downgrade to a specific version. Real package managers typically support versioning.
There may be good or bad reasons why Homebrew can't use the standard /Applications pattern, but did they have to go with "curl | bash"?
That's one of many options, documented at the first text link of the home page. https://docs.brew.sh/Installation
FYI, mas is the equivalent of a package manager for macOS apps (a.k.a. a CLI for App Store). https://github.com/mas-cli/mas
Other than brew, I use mise for everything I can. https://mise.jdx.dev/
For command line apps, the equivalent would probably be statically-compiled binaries you can just drop somewhere in your PATH, e.g. /usr/local/bin/. For programs that are actually built this way (which I would personally call "the correct way") this works great!
If nothing else, consider that the limitations of a statically linked binary match those of a traditional Mac application bundle. While Mac apps are usually dynamically linked, they also include all of their dependencies within the app bundle. I suppose you could argue it's technically possible to open an app bundle and replace one of the dylibs, but this is clearly not an intended use case; if nothing else, you're going to break the code signature.
If the app is not actively maintained, unless trivial, it likely has unpatched vulnerabilities of its own anyway.
And on macOS, if the app is not actively maintained, it usually breaks after a couple major releases regardless of anything else, because Apple doesn't believe in backwards compatibility.
This frustrates me to no end on macOS. Not only do you see crappy installers like you said, but a ton of applications now aren't even self contained in ~/Applications like they should be.
Apps routinely shit all over ~/Library when they don't need to, and don't clean up after themselves so just deleting the bundle, while technically 'uninstalls' it, you still have stuff left over, and it can eat up disk space fast. Same crap that Windows installers do, where they'll gladly spread the app all over your file system and registry but the uninstaller doesn't actually keep track of what went where so it'll routinely miss stuff. At least Windows as a built-in disk clean up tool that can recognize some of this for you, macOS will just happily let apps abuse your file system until you have to go digging.
Package managers on Linux solved this problem many, many years ago and yet we've all collectively decided to just jump on the curl | bash train and toss the solution to the curb because...reasons?
I wish more applications were distributed by the Mac App Store, because I believe App Store distributed apps are more strongly sandboxed and may not allow developers to abuse your system like this.
As I mentioned somewhere side-thread: Debian Unstable is only three minor versions behind the version of Rust that the Rust team is publishing as their public release, but Debian Stable is three years old. For some projects, that dinosaur-times speed. If I want to run Debian Stable for everything except Rust, I'm curl-bashing it.
> they're not worrying about what audio subsystem you installed
Some software solves this by autodetecting an appropriate backend, but also, if you use alsa, modern audio systems will intercept that automatically.
> what side of the systemd turf war your distro landed on
Most software shouldn't need to care, but to the extent it does, these days there's systemd and there's "too idiosyncratic to support and unlikely to be a customer". Every major distro picked the former.
> or which of three (four? five?) popular desktop environments you installed
Again, most software shouldn't care. And `curl|bash` doesn't make this any easier.
> or whether your `/dev` directory is fully-populated
You can generally assume the devices you need exist, unless you're loading custom modules, in which case it's the job of your modules to provide the requisite metadata so that this works automatically.