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

Cross Realm Interfaces #12

Open
bmeck opened this issue Aug 2, 2017 · 8 comments
Open

Cross Realm Interfaces #12

bmeck opened this issue Aug 2, 2017 · 8 comments

Comments

@bmeck
Copy link
Member

bmeck commented Aug 2, 2017

As long as interfaces do not inherit from Object, is it possible to have them be cross realm?

@ljharb
Copy link
Member

ljharb commented Aug 2, 2017

Meaning that if you create an interface, it would become a global in all realms?

As-is, if you pass the first-class interface value across realms, I'd expect it to work.

@bmeck
Copy link
Member Author

bmeck commented Aug 2, 2017

@ljharb global, mmm no it would still have a home realm, but being safely passable between home/target realms without leaking the home realm.

this would require:

protocol InterfaceName {
  youGetThisMethodForFree(...parameters) {
  }
}

To make a youGetThisMethodForFree closure in the target realm though.

@ljharb
Copy link
Member

ljharb commented Aug 2, 2017

ah, you're saying that runtime lookups of globals inside an interface method should use the current realm, not the realm in which they were defined?

@bmeck
Copy link
Member Author

bmeck commented Aug 2, 2017

I need to rephrase all of this with a more concrete example.

// safe realm
const vm = require('vm');
const unsafeRealm = vm.createContext();
let lastId = 1;
const ids = new WeakMap;
protocol HasId {
  id() {
    if (ids.has(this)) return ids.get(this);
    const id = lastId++;
    ids.set(this, id);
    return id;
  }
}
// setup our interface
const implement = vm.runInContext(`(_HasId => HasId = _HasId)`, unsafeRealm);
implement(HasId);

If id is not from the unsafeRealm then we need to start doing wrappers around it. However this is not entirely possible since it is assigned via .implement(...).

In order for HasId/HasId.id to not leak the safe realm, it needs to not have any way to Reflect back to the realm. That means HasId cannot have a prototype that has a reference back to the safe realm via reflection, and the same of HasId.id.

@ljharb
Copy link
Member

ljharb commented Aug 2, 2017

ahhh thanks.

How would you have a function that doesn't inherit from a specific Realm's Function.prototype?

@bmeck
Copy link
Member Author

bmeck commented Aug 2, 2017

@ljharb .implement(target, iface) can specifically see the target before assigning the HasId.id and hook up the prototype/primordials. However, this means o1[HasId.id] === o2[HasId.id] is not always true.

@bmeck
Copy link
Member Author

bmeck commented Aug 2, 2017

looking back on this, it would be a channel to get primordials that would not otherwise be accessible like grabbing them off Object.create(null). However, if .implement does it based upon Realm it was called in rather than target object I can't think of a similar leak.

@mlanza
Copy link

mlanza commented May 5, 2023

FYI. I have a library in which I implemented my own custom protocols long before I was aware of this proposal. I too ran into the realm issue when I was running my code in MS Dynamics where for security purposes the platform creates separate realms for different components.

I ran into issues when my protocols balked at not being able to lookup the symbol on an array. Turns out the array was created in another realm where protocols hadn't been applied. To solve the issue I applied them to all known realms. It seemed heavy handed but worked.

The crossrealm situation is not a simple one to address. You'll see in my README I had to observe certain principles to avoid issues. It's also worth noting I implemented this support long after I had implemented protocols for use in a single realm. So this feature need not encumber the initial specification.

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

3 participants