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

Editorial: stricter notes in HostInitializeSyntheticRealm #315

Merged
merged 1 commit into from Jun 7, 2021
Merged

Editorial: stricter notes in HostInitializeSyntheticRealm #315

merged 1 commit into from Jun 7, 2021

Conversation

Jack-Works
Copy link
Member

Those properties must each be configurable to provide platform capabilities with no authority to cause side effects such as I/O or mutation of values that are shared across different realms within the same host environment.

The current version allows the host to create a mutation of values that not shared across different realms. But IMO that also violates SES requirements.

Example:

// Action of the host in HostInitializeSyntheticRealm
(() => {
    let counter = 0 // internal state
    globalThis.getCounter = () => counter
    globalThis.addCounter = () => void counter++
})()

I changed that to:

Those properties must be configurable. Those properties must have no authority to cause side effects such as I/O or mutation of values (or internal state of the host) that are shared across different realms or within the same realm.

@leobalter
Copy link
Member

This PR is pointing to the opposite direction of the issue we are trying to address here: #261 (comment). Adding internal state will just add more debate.

I intend to discuss the referred issue at the TC39 plenary next week to explore a prose that attends that issue and the current goals described in the text. Please hold until TC39 finds a proper path for this.

@leobalter leobalter closed this May 22, 2021
@Jack-Works
Copy link
Member Author

Adding internal state will just add more debate.

That's why SES removes Math.random right?

@caridy
Copy link
Collaborator

caridy commented May 24, 2021

I think we should discuss this PR in more details @leobalter. I don't see a problem here, also, I don't see the relationship with #261 , maybe I'm missing something. I believe this PR is about the HTML integration, and what APIs to be included, and how to filter those APIs to avoid issues, from less strict to more strict, which I'm always supportive of. cc @erights

@leobalter leobalter reopened this May 24, 2021
@littledan
Copy link
Member

This PR seems reasonable to me. It feels like it's about clarifying the wording for something that we all agree on meaning-wise, so we can iterate on it after Stage 3.

@caridy caridy mentioned this pull request May 27, 2021
7 tasks
@leobalter
Copy link
Member

leobalter commented Jun 7, 2021

After discussions from the previous TC39 meeting in May 2021 and the SES meeting in June 2nd, we decided to relax the restrictions of this host hook to only require the global object must have only have configurable properties.

@Jack-Works I understand this is not the most desirable, and it took some consideration. The fact is: this single requirement still allows virtualization as user code can configure a new realm after instantiation and this can be done effectively as it already reflects reality from what we do today in iframes.

Having a new Realms fully ready for virtualization would be nice, but this is just about reusing user land code and we could explore more of it in the more configurable Compartments API or through extensions for the Realms API once it's shipping.

I'm merging this PR and updating the spec text after it.

@leobalter leobalter merged commit 45e1efa into tc39:main Jun 7, 2021
@erights
Copy link
Collaborator

erights commented Jun 7, 2021

only require the global object to not have configurable properties

Did you mean "require the global object to only have configurable properties" ?

@leobalter
Copy link
Member

Yes, thanks for catching the typo

@Jack-Works Jack-Works deleted the req branch June 8, 2021 00:18
@Jack-Works
Copy link
Member Author

What about authorities? They're allowed now?

@leobalter
Copy link
Member

They are not blocked by this proposal. We really want to avoid such kind of APIs, but that's limited to the user land responsibility.

We believe that, with configuration of a new instantiated realm, user land code can prevent execution of APIs with such effects.

This is also not opening any new precedent, as it already happens today through other forms to use a different Realm. The workaround won't be a new experience.

@Jack-Works
Copy link
Member Author

I don't think that's reasonable. The last TC39 meeting was about if we're going to strengthen the limit but the results into the limits are almost removed? That makes this proposal closer and closer to an unaudited iframe and seems much less useful than before.

@Jack-Works
Copy link
Member Author

What's the reason behind this decision of regression? Aren't we want to have a clean and safe environment?

@leobalter
Copy link
Member

The goal of this proposal is having sandboxing for code execution in a virtualized context.

This goal meets the needs my goal that includes running multiple code scripts in the same web application without generating noise with other scripts and the base platform script.

I understand the Realms API makes us all see much longer on what the future can and should provide us as developers. I believe and support this goal should still be pursued, but gradually. This proposal is not a full resolution of everything we aim for sandboxing. Talk about SES and you'll find much more in the plans. The current Realms API is only one step, there are many more we want to invest.

Rome wasn't built in a day. Having an ordinary object global with all properties configurable makes this proposal already night and day different than iframes. Add the fact you would also be able to use it seamlessly in browsers, node, and any other platforms. Add the fact you can inject code both by string evaluation and through loading modules.

This proposal is still powerful and unlocks a lot. This also unlocks opportunities for all of us to identify and capture another pain points related to using Realms. At some point, we would be able to explore the cost of configuring every new instantiated realm, removing unwanted properties.

Maybe a better opportunity would be exploring what it means to proxy every global property for the virtualization, and finding a way to improve proxies. This is a speculation, but it's not the focus of this current proposal.

Landing the current proposal to ECMAScript is not the end of the road, but an opportunity to explore what comes next. I'd love to get all of this energy you bring to TC39 and translate it in all the work we can do together to further improve.

For now, we need to advance this one step. I'd really appreciate if I can count on you!

@Jack-Works
Copy link
Member Author

I believe and support this goal should still be pursued, but gradually. This proposal is not a full resolution of everything we aim for sandboxing.

But why gradually when you can make things right on the first try?

@leobalter
Copy link
Member

Being able to resolve use cases makes things right. Expanding coverage to a better featured platform is the long term. We need to work everything with implementers and many others TC39 delegates who might not have specific usage for Realms.

As I said, Rome wasn't built in a day.

@kriskowal
Copy link
Member

kriskowal commented Jun 8, 2021 via email

@Jack-Works
Copy link
Member Author

Ok, I understand your point now. If we're not treating it as the lockdown realm (Note I didn't ask to freeze all primordials so my preferred version isn't a "lockdown" realm) I think it's ok.

My last two defense:

Conservatism

That's not great for consistency, but in terms of web compatibility, it's a whole lot easier to undo that, to stop throwing that exception in the future, than it would be to enable Symbol.for symbols and then later disallow them. And, you know, because this is going to be something that people are using all over the world, I think if we ship that more conservative version of this (throwing for Symbol.for symbols), the community will let us know if that was such a painful mistake that we need to revisit it… and then we can do that, right? We can just make it stop throwing and say, “yeah, these symbols aren't going to be collected, but it's better for consistency to allow them in WeakMaps.” So I think I like the strategy/conservatism of that staged approach, of initially disallowing Symbol.for symbols, but considering enabling them at a later date.

This is BN's opinion on Symbol as WeakMap key on May 2021. This argument also applies to the Realm (or maybe we can add options bag in the future?).

Lockdown lib complexity

The lockdown lib must replace the Realms constructor to avoid the subrealm regain the authority.
I'm worrying about if there is some senorials that the library cannot do that.
For example, the lockdown scripts runs as an exception of CSP (by a native webview API or WebExtension) therefore it lockdown the top realm successfully, but it failed to inject lockdown scripts in the sub realm because this time the lockdown scripts does not injected by an priviliged API sus it limited by CSP.

@leobalter
Copy link
Member

This argument also applies to the Realm (or maybe we can add options bag in the future?).

Yes! The idea is exploring and identifying all the pain points and using the current examples directly based on what we get as the implemented Realms. I believe an options bag is pretty doable as a follow up and it's something I'm looking forward to invest time investigating each opportunity of improvements.

The lockdown lib must replace the Realms constructor to avoid the subrealm regain the authority.
I'm worrying about if there is some senorials that the library cannot do that.
For example, the lockdown scripts runs as an exception of CSP (by a native webview API or WebExtension) therefore it lockdown the top realm successfully, but it failed to inject lockdown scripts in the sub realm because this time the lockdown scripts does not injected by an priviliged API sus it limited by CSP.

The subclassing part is right, but I'm not sure if I understand the CSP issue here, I'll review this throughout the day see if I can give you a better answer.

For what I understand there isn't any modification on CSP is applied here. Realm.prototype.evaluate and Realm.prototype.importValue are still subject to the same respective CSP applied to the page.

@Jack-Works
Copy link
Member Author

The subclassing part is right, but I'm not sure if I understand the CSP issue here, I'll review this throughout the day see if I can give you a better answer.

Imagine there is a page with a very strict CSP constraint. The lockdown library was injected via WebView API by the native, or via a WebExtension (https://www.w3.org/TR/CSP3/#extensions), they will be able to do that. But when the lockdown lib tries to execute itself in the replaced realm constructor, it will fail due to the CSP.

@caridy
Copy link
Collaborator

caridy commented Jun 14, 2021

@Jack-Works

Lockdown lib complexity

The lockdown lib must replace the Realms constructor to avoid the subrealm regain the authority.
I'm worrying about if there is some senorials that the library cannot do that.
For example, the lockdown scripts runs as an exception of CSP (by a native webview API or WebExtension) therefore it lockdown the top realm successfully, but it failed to inject lockdown scripts in the sub realm because this time the lockdown scripts does not injected by an priviliged API sus it limited by CSP.

My take on this, which has been discussed extensibly over the years in SES forum. If CSP restricts eval (that can be detected), if they restrict modules, a blob url must be allowed in order to make it work. But that is not different from what you have to do today to achieve any of these. Basically, you have 3 things to be patched:

  1. patch evaluate if available
  2. patch importValue to evaluate the initializer module as bloburl, then evaluate the actual module specifier.
  3. or patch importValue to evaluate the initializer module as regular url from CDN, then evaluate the actual module specifier.

This is not hard, I can probably put together an example of this. Of course, for node, things are different, as it should be, from environment to environment, just like it is today. I will say that this it an improvement from where we are today by providing the ability to modify the environment entirely, which is not possible today.

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

Successfully merging this pull request may close these issues.

6 participants