-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Escaping the sandbox #277
Comments
Hi @nyariv! There is no extra magic in this proposal. This API only exposes realms as already described in ECMAScript.
|
I see. Thanks @leobalter |
@nyariv to add one more note here. This hazard is real, but it is the same hazard that you have in node's VM module, and iframes. There are mechanism to solve this in a generic way, e.g.: a near membrane (which btw, we use very effectively). |
Right, the fact you can pass objects directly to the realm seems like an api that is unsafe to use. If it was possible to add api that pass the object through a function that adds to the realm global object, then at least that native api could be hardened and extended in the future. I personally look forward to realms being released, was just hoping it could be made safe by default. |
@nyariv the ambiguity of such default behavior is the problem, is it a structural cloning? or is it still bound to the original value for dynamic interactions? or is it a membrane? etc. Because we don't know, and not everyone needs such thing, it is better to try to attack that with a different proposal that can work fine with realms, or just leave it to the user-land. |
Thanks @caridy for addressing my concern. You are right, there is no one default that can be assumed correct and each has its own tradeoffs, but at least some warning should be given to not use realms for sandboxing without an appropriate membrane library, and one that can be recommended so that developers will not have homebrew their own security solution. I had been looking for something like realms for sandboxing in the browser and my initial assumption was that it would solve my need, but I had to closely inspect the spec to figure out there is a loop hole. |
Hi @nyariv , you should checkout https://github.com/Agoric/SES-shim , which implements the SES and Compartment proposals. Attn @kriskowal |
Thanks @erights that is what I had been looking for. Very nice! I assume it solves the problem in this ticket? |
Yes! Keep in mind that SES-shim all operates in one realm, the realm it started in. There are no cross-realm issues. I just read the first message of this ticket and we do not have this vulnerability. After Each compartment has its own All these
I find it gratifying to answer this issue because we designed with that threat in mind --- so that property navigation from normal objects would not lead to working evaluators. @jfparadis came up with the idea that |
@erights interesting. Would this protection handle cases where a library might expose I have written a library that tries to solve what you are trying with Compartments, it has minimal api and makes some assumptions on how things should be protected. It accepts a map of whitelisted primordials and custom prototypes and their allowed methods (some stuff in https://github.com/nyariv/SandboxJS It is possible to provide multiple scopes to evaluated code, kind of what you have done with Another feature it has is it allows to subscribe to any property/method access on any object so that the host can either audit the code (especially if it is obfuscated) or allow the creation of frameworks that need to detect state change in evaluated code. I have used this library in a POC ui framework and these features are extremely useful for doing something like it. I would love to discuss more and maybe contribute to Compartments proposal. Would features like these be something that aligns with Compartment proposal's goals? |
I reopened the issue as the discussion is active here. I understand there isn't any action to take for the current proposal but perhaps this discussion becomes even more interesting. |
It’s certainly possible to pass capabilities, including a compartment’s own There are indeed some obvious superficial similarities to what we’re doing with Compartment in the SES-shim! https://github.com/agoric/ses-shim
If I understand this correctly, your ends might be achievable with a Membrane around a Compartment. The membrane would be able to observe all properties that cross into or out of the compartment. |
This library was created before I was aware of realms/compartments proposals and tried to solve the problem of prototype pollution, so seeing what the untrusted code tried to access beyond what was provided to scope externally was needed and could not be achieved by passing in membranes. This proposal in some way solves part of it since it does not matter if a compartment pollutes its own prototypes, but introduces another issue such that one compartment could pollute the prototypes of another (if I understood correctly), and I think my sandbox lib will have to find a way to prevent that, now The scopes related feature could be worked around with membranes in someway, but I tried stick to es based function scopes behavior through its entire implementation so that it behaves exactly the same as if running the code inside layers of functions that I can control. The subscriptions to state that is only passed in and out can be achieved with membranes, yes. |
Actually, in combination with Lockdown, every Compartment has frozen primordials. Although |
OK that's good news. In my case it does break functionality, I cannot use But I do think that deleting/locking globals is not enough, many times a global is needed but has specific methods that should be prevented access too. |
I just want to add that prototype whitelisting also allowed my ui framework to handle html elements securely, I may need the |
Prototype whitelisting is indeed the only way to go. I’ve also learned that SES Lockdown + Compartment is also quite weary of “undeniable intrinsics”, which is the set of prototypes that can be accessed through syntax, like |
There is a way to detect access to any property/method even if not provided under globalThis. You need to create your own evaluation mechanism, using acorn or a similar library, and pass all property/method calls through a validator, this way you can implement prototype whitelisting. This is what my sandbox lib does. It is not widely used nor battle tested but I think conceptually it can prove itself. This is what I hope Compartment proposal would consider implementing. |
@nyariv another option here is what we have been doing around near-membranes, that works very well if you want multi-realms and still have integrity protection for intrinsics of the outer realm. And it is a 4k gzipped library for browsers, and 2k for node: https://github.com/caridy/sandboxed-javascript-environment |
@caridy i am trying to wrap my head around that library, didn't quite understand yet how it is possible to replace an intrinsic that is not accessed through Regarding file size, I also quickly realized acorn is 30kb gzipped just as a parser so i tried to create my own js parsing solution and wanted to see how far i can go with it. I managed to create something that parses the majority of ES, barring ES classes, object/array destructuring and some of the newer ES features. It does not manage to compile something like lodash yet, it is still a WIP and currently requires every statement to end with Having said that, i realize that ES is updated every year and my sandbox code could only grow with each update cycle. |
I believe there isn't much else to do here due to the current Callable Boundary. There is a new discussion championed by @ljharb to get a new copy of clean intrinsics that might address some of the goals here, I guess. Thanks! |
Are the constructors of an externally provided object also sandboxed?
Meaning, is the following code possible:
The above code searches for any objects/functions that were provided externally to the realm and attains the
Function
used to construct them, and executes its own arbitrary code in the external scope. Notice the "sandboxed" code does not directly reference any global objects other thanglobalThis
.The text was updated successfully, but these errors were encountered: