I don't know what the next programming language after Rust will look like, but it will definitely have built-in effects and capabilities.
It won't fix everything (see TARmageddon), but left-pad-rs's build.rs file should definitely not be installing a sudo alias in my .bashrc file that steals my password when I cargo build my project.
Can't help but think that Perl's tainted mode (which is > 30yrs old) had the right idea, and it's a bit strange how few other languages wanted to follow its example. Quoting `perldoc perlsec`:
You may not use data derived from outside your program to affect something else outside your program--at least, not by accident. All command line arguments, environment variables, locale information (see perllocale), results of certain system calls ("readdir()", "readlink()", the variable of "shmread()", the messages returned by "msgrcv()", the password, gcos and shell fields returned by the "getpwxxx()" calls), and all file input are marked as "tainted". Tainted data may not be used directly or indirectly in any command that invokes a sub-shell, nor in any command that modifies files, directories, or processes, with the following exceptions: [...]
That relies on blacklisting all the dangerous APIs which is inherently unreliable. Whitelisting safe things is safer, and the whole strongly typed functional programming world goes that way.
I hope you are right, but fear that there is no way to make such a thing that is usable. You likely end up with complex permissions that nobody understands and so you just "accept all", or programs that have things they must do under the same protection as the evil thing you want to block.
> but fear that there is no way to make such a thing that is usable
The function declarations declare every action it can do on your system, and any change adding new ones is a breaking change on the library.
We've knew how to do it for ages. What we don't have is a good abstraction to let the compiler check them and transform the actions into high-level ones as they go through the stack.
You end up just declaring you can do anything because every time a function legitimately needs to do something every other function up the chain needs to be updated to do that same thing (even if in practice that can never happen but the compiler can't prove it).
Like you say we don't have a good abstraction for this.
The project I work on is 15 years old. A number of functions have got more ability over the years. Low level not so much but mid and high level a lot has changed from our oririnal plan
The ones near the top changing abilities is perfectly fine, both as a design rule and as them not leading to cascading changes in declarations through all your code.
The problem is on the ones deep down. And we don't have very good tools for dealing with them, but they are perfectly workable even with what we have today.
(A second large problem is on frameworks running on the top-level of your app. We have some tools for dealing with those, but the situation here is way worse than for libraries.)
It won't fix everything (see TARmageddon), but left-pad-rs's build.rs file should definitely not be installing a sudo alias in my .bashrc file that steals my password when I cargo build my project.