In an ocap system such as SES https://github.com/Agoric/SES , an object can only directly cause effects on the world outside itself by using the capabilities it holds. Objects come in graphs held together by references, so an object can still only cause effects, directly or indirectly, according to its connectivity to the rest of the system via references. The different between direct effects vs general causation is the difference between permission and authority [1,2]. Permission is often vastly easier to reason about than authority, but our safety depends on reasoning about limits on authority.
The event-stream exploit would have been prevented merely by practicing the principle of least permission. Hence this article did not need to go into these subtleties. Hence, this exploit is a good example for introducing people to these concepts, tempting them to dig deeper [3].
[1] Paradigm Regained http://www.erights.org/talks/asian03/paradigm-revised.pdf
[2] Permission and Authority Revisited https://ai.google/research/pubs/pub45570
[3] References page https://agoric.com/references/
https://www.youtube.com/watch?v=9Snbss_tawI&list=PLKr-mvz8uv... is my presentation to the Node security team, explaining many of these issues prior to this particular incident.
my app imports an http request library and gives it net permissions
my app imports a templating library and gives it no permissions
the templating library is malicious and tries to import well known http request libraries, and finds the one i imported, which has been given net permissions.
or what if you give the templating library a mixin of some sort which accidentally exposes the privileged http library
The best way to enforce POLA, and especially this particular problem of not allowing libraries to have access to each other, is object capabilities (ocaps) [3]. An object capability combines designation with authority -- if you have access to a capability, you can use it. If you don't have access, you can't use it. You can think of this (very roughly) as a key to a car as opposed to your name being on a guest list for a party. I didn't really touch on ocaps in this piece, but it's a necessary component for being able to enforce POLA well.
[1] https://developers.google.com/caja/
[2] https://www.youtube.com/watch?v=3ME7oHHQbuM
[3] http://habitatchronicles.com/2017/05/what-are-capabilities/
We're not focused on security (yet), but any help we can get to move the ecosystem towards a stricter model will help you in the long term (by ensuring that common tools will be compatible with the even stricter model you're advocating).
That's why there is a SecurityManager: https://docs.oracle.com/javase/tutorial/essential/environmen... that - if anything - is extremely granular.
There's at most one SecurityManager per application, meaning you can't in general use it for fine-grained confinement. It's only "granular" in the sense that requested permissions can be arbitrarily finely subdivided. There's no notion of intra-application invocation contexts, making it vulnerable to "confused deputy" problems, including things like the event-stream incident.