Skip to content
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

Protecting prototype accross the sandbox #55

Open
Jack-Works opened this issue Sep 20, 2019 · 3 comments
Open

Protecting prototype accross the sandbox #55

Jack-Works opened this issue Sep 20, 2019 · 3 comments

Comments

@Jack-Works
Copy link
Contributor

In my use case (web extension polyfill), codes run in the sandbox need to access to the "clean DOM" that means any changes outside of the sandbox can not affect the inner side of the sandbox.

Currently, I'm making a copy of the global object and provide it to the realms.

And this cause problem on the prototype:

For example:

// This file is running outside of the sandbox.
HTMLElement.prototype.a = 1
const div = document.createElement("div")
div.a // 1
// This file is running in the Web Extension polyfill, which based on the realms-shim
HTMLElement.prototype.b = 2
// Web Extension needs to access an isolated JS environment but a shared DOM environment
// So I copied everything on the globalThis. So HTMLDivElement and document is also accessable from the inside of the realms shim.
const div = document.createElement("div")
div.b // 2

After these two files run, both a and b are accessable from the outside world and the inside world.
Ideally it should only accessable from where it get changed. (a in the main frame and b in the realms shim)
I have some idea about how to protect the prototype (by replacing prototype with a Proxy) but not clear if realms shim will give some help.

@caridy
Copy link
Contributor

caridy commented Sep 20, 2019

@Jack-Works I believe what you're asking here is a use-cases solved by https://github.com/caridy/secure-javascript-environment, which is an abstraction on top of realms-shim. In the examples, you there are two explicit example show casing how expandos are handled, and how polyfilling (changing the protochain of a provided DOM api), without affecting the outer realm.

Now, the ambiguity of your example comes from the first line (HTMLElement.prototype.a = 1), which is executed in the outer realm, there are 3 main things to keep in mind/discuss:

  • outer realm should be prepared (usually referenced as polyfilling the outer realm), in case it is broken for the realms-shim point of view.
  • how do you know that HTMLElement.prototype.a = 1 is not part of that preparation?
  • usually, the outer realm is protected, and mutations on it should be safe if all untrusted code is executed inside a sandbox.

@Jack-Works
Copy link
Contributor Author

In our use case, the outer realm is untrusted and code run in the sandbox is trusted. We need it to run in the sandbox to avoid secret information leak out to the dangerous outer realm.
We're loading our WebExtension polyfill by WKWebkit and we can ensure we can run our code before any other dangerous code runs. So when we're preparing the execution environment of WebExtension, the globalThis is clean, not modified by anyone.

@Jack-Works
Copy link
Contributor Author

So execution order of our code is:

-> Webview onCommitted. The JS environment is just created. No code has run.
-> Inject WebExtension polyfill, prepare the environment. At this point, the JS environment is clean. WebExtension polyfill will copy everything on the globalThis for future use.
-> Webpage loaded, run its own code. JS environment is polluted. (HTMLElement.prototype.a = 1
)
-> Codes now loaded in WebExtension, with a clean environment preserved in step 1. (HTMLElement.prototype.b = 2)

-> Now both outside code and inside code are ready.

Expected outside code cannot access HTMLElement.prototype.b because it's secret info.
Expected inside code cannot access HTMLElement.prototype.a because it may be dangerous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants