I think the GP meant downloading random binaries through a web browser, as most people do on Windows. Package managers with hash verification are a million times safer than that.
Nothing short of a full code review will save you from a malicious supply chain attack. This is currently exploding with NPM as well, so building from source doesn't save you here either. See the node-ipc debacle from a few weeks ago [0], and also my own post from last week about a malware infected NPM module [1].
The reality is that yes, the days of being able to trust anything downloaded from a stranger on the internet are pretty much over now. But known-hash package management is still a good first layer of security versus downloading random binaries from the web.
Node is just insane, always was, along with the curl | bash crowd.
Madness.
Nonsense. Or, at least, an oversimplication.
https://medium.com/agoric/pola-would-have-prevented-the-even...
Nothing short of full code review will ensure that malicious code from a dependency doesn’t get into your program at all, but the capabilities of that malicious code once it does get into your program can certainly be limited.
That's a tall order for the open source community when it comes to a volume of packages like npm or composer.
You can logically look at lpad as a package and say "We're padding strings, we don't need to do anything with network traffic or disk reads" but building an automated system to make that evaluation and saving that evaluation in a tamperproof manner is going to be hard... and what happens if lpad starts trying to do a better job - operating correctly in left-to-right character sets and in languages where alignment is dictated by hyphens instead of blank space.
Code isn't simple and while the above statement may seem hyperbolic I think it's just because most of us accept the risk, it's highly unlikely that malicious supply chain attacks will suddenly sink our businesses so we accept a reasonable level of security in exchange for what feels like a modest risk but actually fully 100% preventing that risk? You'll need to check every usage scenario on every set of hardware and go through that code with a fine toothed comb.
If you're expecting to have to craft ACLs program-wide for that package, then sure, that's going to be hard. That's more coarse-grained than what I'm talking about here though.
Imagine, if you will, a programming environment where modules you load don't have any authority to access the network, filesystem, etc unless you pass them in. They're just not in scope. In such a language, the default way to grant HTTP access might look like this in pseudo-Python:
http = require("http")
myMaliciousLibrary = require("myMaliciousLibrary", http=http)
Now, this library has the problem you mentioned; it can make arbitrary outgoing HTTP requests, meaning it can send any metrics it collects to an ad server. It can't access the filesystem because the filesystem isn't in scope either, so what it can collect is limited, but still more access than it needs. So here's one way you might fix that (obviously highly simplified/incomplete in its implementation): class ProxyHTTP(origin="https://example.com", http):
def __init__(origin="https://example.com"):
self.allowed_origin = origin
def get(origin, path="/"):
return http.get(self.allowed_origin, path)
http = require("http")
myMaliciousLibrary = require("myMaliciousLibrary", http=ProxyHTTP(origin="https://good-site.example.com", http))
Now, this version of myMaliciousLibrary gets an object that looks like the http library it would normally use; it just happens to ignore the origin parameter that the library passes to it and uses the one it was initialized with instead. Now, that library can make requests to good-site.example.com, but if it tries to make a request to adserver.evil.com, it'll go to good-site.example.com instead. (You might also imagine a version of ProxyHTTP that just throws an error if the request's origin isn't the same one it was initialized with, or isn't in a list it was initialized with.)Most of today's programming languages aren't strict enough to enable this of course; JavaScript isn't there yet for example, and most other languages aren't even close to being able to do this. But that's mostly because they don't provide strict enough encapsulation, not because they're lacking some complex security enforcement mechanism.
> I think it's just because most of us accept the risk, it's highly unlikely that malicious supply chain attacks will suddenly sink our businesses so we accept a reasonable level of security in exchange for what feels like a modest risk
I just think people are accepting way more risk than they realize, given the number of dependencies in modern applications and the amount of access each of those dependencies have. It feels crazy that any one of those dependencies in any application could exfiltrate massive amounts of sensitive data from any machine it happens to run on.
There are ways you can instruct an OS to block calls to certain library functions/memory ranges (i.e. remove and grant elevations privileges) but I think such a system would need to be designed from the ground up. If you can still `require(lib/reallyOldCurl)` then your protections might allow linters to be able to mark packages as unsafe, but I think it'd be extremely difficult to block access without an extremely fundamental design intent.
I appreciate your reply quite a bit though as I was envisioning the restrictions being defined on a universal package level (aka lpad is given no disk access) rather than being delegated to the consuming developer.
Actually, binary package managers are arguably strictly less safe than getting the binaries directly from upstream because you've just introduced a (literal) "man in the middle", who might have their own agendas and their own need to monetize. Like, for example ... SourceForge did. In a different context these MITM attacks can go wrong even when they're genuinely trying to be helpful, as we may remember when Debian accidentally patched out important code from a core encryption library and caused everyone to get the same SSH keys.
Generally for security you want to reduce the number of middlemen who can tamper with things, unless those middlemen are explicitly adding some sort of security value by pre-tasting the apps. So, Apple app reviewers: yes. Linux distro maintainers: sorta sometimes. Homebrew, winget etc: no. It's all automated.
https://www.vlcdownload.com
https://www.vlcdownloads.com
https://www.videolan.com
https://www.vlc.com
https://www.downloadvlc.com
https://www.videolan.org
https://www.videolan.co.uk
https://sourceforge.net/projects/vlc/
In linux/Mac, I can "sudo apt install vlc", "sudo yum install vlc", or "sudo brew install vlc". I know I'm getting a valid and good software delivery. It just works. No malware. No sketchy websites. No malware packages.On Windows, well, you feelin lucky?
Chocolatey does have it's quirks though, there is both a '7zip' and a '7zip.install' package, it's not intuitive what the difference is.
Doesn't chocolatey fit the bill?
choco install vlcBut there are package managers for Windows, aren't there?
Microsoft even has its own app store, that you need to use to install applications such as Windows Terminal.
People often install software on Linux and macOS by downloading installers using a browser. In fact, that's how non-bleeding edge versions of Xcode are installed.
apt-get install wine
Did you just get Wine from upstream? The answer is no and this has wasted significant amounts of time of Wine developers in the past. I used to be one and spent way too many free evenings and weekends debugging subtle crashes reported by users, that turned out to be packaging bugs introduced by men-in-the-middle.
Lots of other Wine devs had the same experience, so at that time we had a policy that if someone reported a bug the first instruction was to uninstall their distro package and to install the binary packages produced by the Wine project itself. Sometimes users were upset by this advice, but it resolved a significant number of "bugs" that were being added by the distributors.
For lesser known projects I just cross my fingers, but typically lesser known projects are less likely to have malware posing as them
a) Download file.EXE binary from somewhere
b) run: certutil -hashfile file.EXE (which spits out hash value)
c) search for hash value obtained at step “b” on a site like: virustotal.com : it tells you if malware is detected
d) run: file.exe (if no malware detected)
I honestly couldn’t find a better method on MS Windows. Other suggestions?
Maybe I could have been more explicit, I took for granted that the context would be pretty obvious to most people. Sorry about that.
I've only been a sysadmin and developer since the mid 90's so for a fact I'm still in the process of getting my head out of my ass.
Gentoo's package manager mostly builds from source (though there are some binary packages available for Gentoo -- usually of huge binaries like Firefox, which take forever to build and which you have to update pretty frequently).
Guix can also build from source.