Java has actually had this built in for a long time now. A SecurityManager allows you to restrict access to things like the filesystem and the network (and whatever else you want). I have never seen it used in a real codebase.
Elasticsearch is actually using SecurityManager with quite thoroughly locked down policies; and it seems that this actually saved ES from being vulnerable to the RCE.
The irony is now that OpenJDK just recently decided to deprecate the SecurityManager in Java 17 and remove it in Java 18.
We actually use it in a real codebase. When the software is running on "developer mode" (on a developer's machine), we install a SecurityManager which denies all outbound connections except for localhost by default.
The security manager represents a flawed way to do it. It tries to catch up and restrict an application after it already has access to the releveant APIs. Forget to restrict just one API, and the sandbox can be escaped. Usually, the integration with the security manager requires intimate knowledge of the application.
Javascript follows a better approach because it has a small core API. All other APIs have to be explicitly injected and permitted by the host program.
Java's SecurityManager is very different from capability-safety. It's much more like setuid: SecurityManager allows or disallows network accesses depending on what code is running. (Literally by inspecting the stack)
https://docs.oracle.com/javase/tutorial/essential/environmen...