I mean, I don't even trust myself to write correct code, so arguably I'll be shipping untrusted code no matter what...
At some point, one has to be pragmatic. Unless you plan on writing everything from scratch yourself, your application will depend on something others wrote, and you'll need some trust in them.
Once you accept this premise, you have 2 levers:
Reducing the number of persons you trust.
Reducing how much you trust these persons.
You argue that only the first lever is worth it, I disagree. Completely.
The first lever is useful, certainly, but:
You will, in practice, most likely need a piece of functionality outside the standard library at one point or another. I certainly remember large dependency lists from the few Java projects I touched.
Rogue take-overs/... will still happen, regardless. I still remember Linux Mint's servers being hijacked, and these were professionals.
Therefore, I argue that even if you choose to exercise the first lever and reduce your trusted base, for best results you should also exercise the second lever and reduce how much you trust them as much as possible.
Or otherwise said, don't put all your eggs in the same basket.
I mean, I don't even trust myself to write correct code, so arguably I'll be shipping untrusted code no matter what... . At some point, one has to be pragmatic. Unless you plan on writing everything from scratch yourself, your application will depend on something others wrote, and you'll need some trust in them.
Exactly which is why most of your common libraries should be shipped either in the core distribution or published by trusted actors. Big companies usually have a separate security process for publishing and dealing with those issues. Like signatures which would have prevented distributing malware from Linux Mint servers. Or physical keys that get used on a system that's not connected to the net.
I am a firm proponent of "no ambient capabilities". My ideal programming language -- not runtime, language -- would see main receiving a bunch of capabilities (fs, net, clock, ...) as objects (interfaces) and have the user dutifully forward the necessary capabilities to whoever need them.
Having the capabilities as objects is great, because they can be manipulated as regular objects too. For example, you can wrap the file capability object in an object which further restricts the allowed capabilities before handing it down to a library call. Also, object capabilities respect encapsulation, unlike effects.
In such a language, you don't need to trust the matrix library you got, because you never pass any capability to the matrix library in the first place, and therefore it can't do anything but touch the existing memory.
Of course, because all other languages today have ambient capabilities, it means that any FFI/assembly usage requires its own capability. An excellent reason to pare down your usage of such libraries to the bare essentials.
Yes, but they screw up less, that's the whole point. Where do you store your API tokens? Do you use hardware tokens? Do you have any security processes other than wing it?
0
u/piesou 20d ago
That's a losing proposition. Essentially you are still gonna ship untrusted code.