4 ms·
Yup, this is all really hard, which is why it hasn't been much more than a research project up to this point. If I had to guess, the supply chain problems that
by jerf 1y ago
Yup, this is all really hard, which is why it hasn't been much more than a research project up to this point.
If I had to guess, the supply chain problems that may eventually cause this to be created will need to get, oh, I don't know, call it two orders of magnitude worse before the system as a whole really takes note. Then, since you can't really write a new language just for this, even though I'd like that to happen, it'll get bodged on to the side of existing languages and it won't be all that slick.
That said, I do think there's probably some 80/20 value in creating an annotation to the effect of "this library doesn't need filesystem access or sockets" and having perhaps a linter or some other external tool validate it externally to the main language compiler/runtime. The point of this would not be to solve the capabilities problem for libraries that are doing intrinsically tricky things, because that's really hard to do correctly, but just to get a lot of libraries out of the line of fire. There's a lot of libraries that already don't need to do those things, and more that could easily be tweaked to just take passed-in file handles or whatever if there was a concrete reason to design them that way.
The library that I personally could do the most damage with on my GitHub is a supervision tree library for Go. It doesn't need any capabilities to speak of. The closest thing is that you can pass in a logger object and that is constrained to specific calls too. Even a hack that just lets me say that this library doesn't need anything interesting would at least get that out of the set of libraries that could be exploited.
Or to put it another way, rather than trying to perfectly label all the code doing tricksy stuff, maybe we can start by labelling the code that doesn't.
I'd also point out that I think the question of libraries is different than things like Chrome isolation. Those things are good, but they're for treating data carefully and limiting blast radiuses; I'm looking at the problem of "if I download this library and miss one single file is it going to upload every AWS token it can find to someone who shouldn't have them".
- pyinstallwoes 1y agoShouldn’t it be automatic based on behavior? An annotation is ripe for exploitation if the system itself can’t make sense of its own parts.
- jerf 1y agoThat would be preferable, certainly. I'm staying vague because there's a world of differences in how all the languages would most easily be able to implement something like this and I'm trying to stay language non-specific. Imagine how you'd solve this in Rust versus Ruby.
- mlinksva 1y agoI did not see a link to your screenshotted comment in the article so looked it up, https://news.ycombinator.com/item?id=43936830 https://news.ycombinator.com/item?id=43936830 to save others the work (not the whole thing is screenshotted, and the comment and its thread are good, thanks!)
- mike_hearn 1y agoOops, sorry, there was a link and it seems to have been removed during editing. I put it back, thanks!
- mike_hearn 1y agoThe right place to start is definitely a deep study of the Java SecurityManager because it came the closest to what seems to be needed here, and yet failed. One reason it was hard to use is that many permissions transitively implied others without that being obvious. For example, you said you want an annotation that lets you drop filesystem access or sockets. But that's not enough, is it? - Loading native code = granting all permissions - Access to the unsafe package = granting all permissions - Many syscalls that write data to user buffers = granting all permissions - Being able to run a sub-process = granting all permissions So you need at minimum to exclude all of those too. But then you also have: - Tampering with global state of any kind e.g. the default HTTP server can be mutated by anything in Go (I think?). If you can modify the logging system to write to a new location you might be able to use that to escape the sandbox. - Deserialization of objects can be a sandbox escape. And then what about the threat model? If you can cause every process including your library to segfault simultaneously, then that's a DoS attack on a company that can be profitably used for extortion. Are DoS-driven extortions in-scope or out? This is why System.exit is a permission in the SecurityManager. And so on. The large number of ways you can accidentally configure an exploitable set of permissions is huge, and because nobody seems to care much, there was no tooling to help avoid such misconfigurations.