6 ms·
If anything is going to put capabilities into the programmer ecosystem, I think it's this problem. The neat thing about this particular problem is that you can
by jerf 2y ago
If anything is going to put capabilities into the programmer ecosystem, I think it's this problem.
The neat thing about this particular problem is that you can do some really coarse things and get some immediate benefit. Capabilities in their original form, and perhaps their truest form, carry down the call stack, so that code can do things like "restrict everything that I call can only append to files in this specific subtree" in the most sophisticated implementations. But you could do something more coarse with libraries and just do things like "These libraries can not access the network", and get big wins on some simple assertions. If you're a library for turning jpegs into their pixels, you don't need network access, and with only a bit more work, you shouldn't even need filesystem access (get passed in files if you need them, but no ability to spontaneously create files).
This would not be a complete solution, or perhaps even an adequate solution, but it would be a great bang-for-the-buck solution, and a great way to step into that world and immediately get benefits without requiring the entire world to immediately rewrite everything to use granular capabilities everywhere.
- marcosdumay 2y agoJust to say, but You are describing an effect type system. (Or, to the "types are static" people, possibly a dynamic effect system.) Capabilities taken literally are more of a network thing (it's how you prove you have access to a computer that doesn't trust you). On a language, you don't need the capabilities themselves.
- wyago 2y agoEffect typing can achieve capability security statically, but I've also frequently seen capabilities used to describe dynamic capability systems via various methods involving passing capabilities down as reified objects of some sort. This of course also depends on some related static guarantees that a function can't access ambient capabilities not passed directly in their arguments, but this is a much simpler static guarantee than effect typing and doesn't require specific analysis over normal parameter types.
- jonahx 2y ago> Capabilities taken literally are more of a network thing (it's how you prove you have access to a computer that doesn't trust you). On a language, you don't need the capabilities themselves. You may be thinking of the term in a different context. In this context, they are a general security concept and definitely apply to more than the network, including languages: https://en.wikipedia.org/wiki/Capability-based_security https://en.wikipedia.org/wiki/Capability-based_security http://habitatchronicles.com/2017/05/what-are-capabilities/ http://habitatchronicles.com/2017/05/what-are-capabilities/ (this is a great article) https://www.ponylang.io/ https://www.ponylang.io/ etc...
- bluGill 2y ago> On a language, you don't need the capabilities themselves. Why not? Sometimes I want that. Just today I was looking at some code and realized that it was being used by groups that shouldn't. The code needs to be there and is great for the correct users, but someone is going around our architecture and we didn't notice it.
- jonahx 2y agoYou are replying to the wrong post. I was quoting the GP.
- ajb 2y agoCapabilities are more general than that. They have been around for a long time; one academic design implemented them in hardware in 1970[1]. they can be used in as fine grained a way as 'you are allowed to access this array in memory and nothing else'- which is the sort of thing that needs to be built into languages to be maximally useful. [1] https://en.wikipedia.org/wiki/CAP_computer https://en.wikipedia.org/wiki/CAP_computer
- convolvatron 2y agoI disagree about your last point. I looked at a product design once which allowed one to associate a profile with each third party library. accesses across library boundaries were implementing using classic call gates from segmented architectures which could change memory visibility and syscall filtering. so while I agree that language integration is really useful, I think you can get a lot out of appropriate support in the runtime, most notably the library loader.
- ajb 2y agoYes, that's why I said "to be maximally useful" instead of "to be useful"
- justinpombrio 2y agoYou can do a lot with capabilities at the language level, if the language supports it. It doesn't require effect types: it's extremely boring from a type system perspective, which is an advantage. Imagine these changes to a language, making it "capability safe": - There is a `Network` object, and it's the only way to access the network. Likewise, there's a `Filesystem` object, and it's the only way to access the file system. - Code cannot construct a `Network` or `Filesystem` object. Like, you just can't, there's no constructor. - The `main()` function is passed a `Network` object and a `Filesystem` object. Consider the consequences of this. The log4j vulnerability involved a logging library doing network access. In a capability safe language, this could only happen if you passed a `Network` object to the logger, either in its constructor or in one of its methods. So the vulnerability is still possible. But! Now you can't be surprised that your logger was accessing the network because you gave it the network. And a logger asking for network access is sufficiently sketchy that log4j almost certainly would have made network access optional for the few users that wanted that feature, which would have prevented the vulnerability for everyone else! I talked about there being a single monolithic `Filesystem` object. That is what would be passed into `main()`, but you should also be able to make finer grained capabilities out of it. For example, you should be able to use the `Filesystem` object to construct an object that has read/write access to a directory and its subdirectories. So if a function takes one of these as an argument, you know its not mucking around outside of the directory you gave it. Capability safety within a language is stronger than the sort of capability safety you can get at the process level or at the level of multiple machines. But we want those too!
- gnafkcud 2y agothis was the original approach for Java, and the main idea behind being able to ship untrusted apps directly to the user and run them in the browser tomcat also gave different privilege levels to different parts of the classpath nice idea, but didn't seem to work in practice
- justinpombrio 2y agoThat's what I'm calling capabilities at the application level (where you say "this .jar can't access the network"), rather than at the language level (where you say "this function wasn't given access to the network as an argument"). I don't think any widely known language has tried capabilities at the language level. (The language not widely known that does it is E.) The real power will come when you can mix them. In one direction, that looks like `main()` not getting passed a `Network` object because the ".jar" wasn't granted network access. In the other direction, that looks like the system C library you invoked failing to access the network because when you invoked it from Java you failed to provide a `Network` object, so it was automatically sandboxed to not be able to access the network.
- jonahx 2y agoCapabilities are the only way. It is insane to me that in 2025 there is no easy way for me to run a program that, say, "can't touch the filesystem or network". As you say, even a few simple, very coarse grained categories of capabilities would be sufficient for 95% of cases.
- IncreasePosts 2y agobubblewrap?
- jonahx 2y agoNothing in the container space would qualify as "easy" for me. I am talking about native OS features. Also linux only (afaik)... Or even, for that matter, some sane capabilities for browser extensions.
- BeefWellington 2y agoSELinux! Half jokes aside, I'd love to be able to have a decent mobile style permissions experience on browser extensions and desktop apps.
- taeric 2y agoI'm curious what all you want to run that you don't want to access the filesystem? Or the network? Like, I get it for a few things. But it is a short path to wanting access to files I have created for other things. Pictures and videos being obvious files that I likely want access to from applications that didn't create them. Similarly, it is a short hop from "I don't want any other application to be able to control my browser" to "except for this accessibility application, and this password management application, and ..." As we push more and more to happen in the browser, it should be little surprise that we need more and more things to interact with said browser.
- jonahx 2y agoI think you misunderstood. Among the coarse grained capabilities I mentioned would be "access to folder X and it's subfolders" (read or write). But to answer your question there are, eg, tons of programming packages in any language that I want purely for their computational abilities, and I know this for certain when using them. In fact for the vast majority of GUI programs I use, or programming packages I use, I know exactly what kind of permissions they need, and yet I cannot easily restrict them in those ways.
- Veserv 2y agoThat is almost the exact backwards way to talk about capabilities. It is not about "restricting" access, it is about "granting" access. "These libraries can not access the network." No. "These libraries have not been given access to the network (and by default none are given access)." From an implementation perspective, this is just passing in access rights as "local" resources instead of using "global" resources. For instance, it is self-evident that other code can not use your B-Tree local variable if you did not pass a reference to it to any called functions (assuming no arbitrary pointer casts). You just do the same with these "resources". It is just passing things to functions instead of relying on globals. The only difficulty is making these actions/resources "passable", which is trivial at the language-level, and "fine-grained/divisible" to avoid over-granting.
- jerf 2y agoClearly these things are dual and you can easily model them either way, and indeed, should think about them both ways.