4 ms·
As opposed to downloading a binary and running it? We don't verify what the binaries we download contain, why do it for a bash script?
by willeh 6y ago
As opposed to downloading a binary and running it? We don't verify what the binaries we download contain, why do it for a bash script?
- dastx 6y agoI suppose the difference is iff people do very script before they run, this could bypass it. But I think, those people would definitely download it, inspect it, then run the downloaded script.
- VBprogrammer 6y agoI think it would take next to no effort to hide something in a bash script in such a way that it passed casual inspection even by an expert. See code obfuscation competitions for examples.
- OskarS 6y agoBinaries we download and run (as well as packages from package managers) are generally cryptographically signed by people you trust. Shell scripts you curl into bash are not. It is generally MUCH easier to compromise a website and insert your own malicious script than it is to compromise a developer's secret key, which is usually stored much more securely. Put it like this: if an attacker compromised Rust's website and put in their own malicious Rust installer, macOS and Windows would both show a very scary warning that's like "This is unsigned! Don't run this!" (macOS would even refuse to run it unless you did the right-click to open trick). A Linux package manager would refuse to install such a package outright, unless you --forced it. Not so with curl-to-bash, it would just silently compromise your computer. Basically, if you believe that code signing is a good thing for security (and I think we all do), curl-to-bash is awful security practice, and you should manually review the script.
- aesyondu 6y agoPardon my ignorance, but couldn't we just cryptographically sign bash scripts as well? Perhaps modify the installation script, something like `curl | some-verification-tool | bash`
- OskarS 6y agoNot easily, and probably not in a way that would work on all different systems (different distros/os's trust different keys).
- Arnavion 6y agoYou can. PowerShell already has a 15-year precedent of signed scripts - you generate a signature and embed it in the script in a specific way, and the shell can be configured to only run scripts if their signature is valid. (PowerShell script signing is based on standard Windows codesigning certificates, but of course this hypothetical bash script signature verifier can use GPG keys instead.)
- iso1631 6y agoThose who do not understand package managers are doomed to rewrite them. Badly.
- leokennis 6y agoNot that it would fix anything, but wouldn't it be possible to: - Store the install script on www.xyz.com/install.sh - Store the hash of the install script on www.abc.com/hash.dat Then in the installation command: - curl the install script from www.xyz.com/install.sh - hash it - curl the hash from www.abc.com/hash.dat - compare the computed hash with the "curl'd hash" - only if they match, pipe www.xyz.com/install.sh to bash In that case, a malicious actor would need to hack at least two locations to be successful.
- jorangreef 6y agoThe malicious actor would simply edit the install script to comment out the checksum verification step, since they already own the script.
- leokennis 6y agoAh yes...good thing I don’t work in IT security...
- jorangreef 6y agoNo worries, I've made the same mistake and everyone in software security probably makes that mistake at some point.
- willeh 6y agoExcept if you're using Homebrew where nothing is signed, so signing is not as ubiquitous as you seem to think. But signing is largely a moot point as people will follow the instructions on the website where a clever attacker would simply create their own cryptographic keys sign it and provide instructions for adding it to your keychain to the compromised website. Public key crypto does not solve establishing trust for an actor. It can only do so through delegation which as we have seen with the deprecation of EV certificates (CAs no longer being trusted to establish the identity of legal persons) is not something that is easy to get right. Certainly it is better to trust the maintainers of your operating system/package manager than a random website. However they only sign things where they have done due-diligence on the project, which is a slow process, too slow for projects with faster release cycle such as Docker or Rust.
- megous 6y ago> Public key crypto does not solve establishing trust for an actor. It can only do so through delegation which as we have seen with the deprecation of EV certificates (CAs no longer being trusted to establish the identity of legal persons) is not something that is easy to get right. Public crypto can help carry the established trust. Say you track some developer's work and the dev behaves consistently in a trustworthy manner, his signing key can be used to help carry this trust forward, so that after a while you don't need to keep checking and just rely on the assumption that dev is probably honest going forward + crypto to verify you're really using this developer's output. No need for delegation. Delegation doesn't solve trust anyway, only identity verification.
- skissane 6y ago> Binaries we download and run (as well as packages from package managers) are generally cryptographically signed by people you trust. Shell scripts you curl into bash are not. There is no reason in principle why a shell could not implement digital signatures. bash could have a "--require-signature" option where it looks for a GPG signature appended to the end of the script, and refuses to run the script if the signature is missing or the signer is untrusted. (No idea if the Bash maintainers would be willing to accept a patch adding such a feature if someone were to write one; but, signed scripts is something supported by PowerShell, although most people's experience with it is limited to turning off the default setting which requires all scripts to be signed.) A related question – what's the difference between downloading an unsigned script over HTTPS versus downloading a signed script (whether over HTTPS or just plain HTTP)? Ideally, the code signing is done offline, so an attacker that compromises the HTTPS server gets the HTTPS private key but not the code signing private key. However, I suspect that ideal often isn't actually obtained; offline code signing can be a pain for CI. If someone has a CI pipeline which signs the code and then deploys it to the HTTPS server, then all an attacker has to do is compromise access to that CI pipeline and neither HTTPS nor code signing will stop them.
- OskarS 6y ago> There is no reason in principle why a shell could not implement digital signatures. They currently don't, though, which is the point :) The reason in principle this might not work is that different distros and os's trust different keys. Fedora trusts different keys than Ubuntu, than Arch, than macOS, etc. > Ideally, the code signing is done offline, so an attacker that compromises the HTTPS server gets the HTTPS private key but not the code signing private key. I don't think this is necessarily the case. Even if you gain access to the server, HTTPS keys are usually stored in such a way that only root can read them, right? So if you only compromised a non-root account, you wouldn't necessarily be able to read them (I might be wrong about this, I don't do this kind of thing professionally). Also, you could imagine that the script is not stored as a file, but in a database or something, and then you could compromise it with SQL injection or a similar technique. That would allow you to change the script without any access to HTTPS keys. > However, I suspect that ideal often isn't actually obtained; offline code signing can be a pain for CI. You're probably right about this, but this is a great example of why you shouldn't use the same key for both code signing and HTTPS.
- tzs 6y agoThe biggest issue is not bash script vs. binary. It is that “curl | bash” does not save the script locally. If something goes wrong, you can’t examine the script afterwards to help figure out what happened and how to recover.