Skip to content

Conversation

@jrvidal
Copy link

@jrvidal jrvidal commented Feb 22, 2023

👋 Hi there! At Stackblitz we rely heavily on Comlink (as you might already be aware), and we're big fans, thanks for you work!

Recently, we've encountered a situation where one of our Comlink endpoints is not fully under our control (see @webcontainer/api). In this scenario, we would welcome some extra assurance that what we expose is exactly what we intend to, and nothing else. You could argue that Comlink, being about seamless RPC, might not 100% be the best fit for it, but we went ahead anyway because of its ergonomics 😅

This patch is more or less what we've added to a internal fork for the purposes of "hardening" Comlink.expose(). It is somewhat nice b/c it only affects the "server" side endpoint, while the "client" endpoint does not need any new codepath.

I am not fully convinced this belongs in Comlink proper, but we wanted to show it to you anyway. We are actually considering moving this "hardening" to a external Proxy that wraps our exposed objects. One disadvantage of doing that is that, AFAICS, when Comlink traverses a path for a exposed object, we would need to create proxies on the fly.

⚠️ This patch is adapted from something we built on top of Comlink 4.3.0, so it is not as thouroughly tested as it should be.


This adds ExposeOptions to Comlink.expose(). options.spec allows you to specify a "spec" of the object being exposed, a description of what the other side of the endpoint can do with the object. For instance, with the following spec:

Comlink.expose(obj, ep, {
  spec: {
    walk: "function",
    bar: { jump: "function", name: "primitive" }
  }
});

the other side of the endpoint cannot perform certain actions:

const obj = Comlink.wrap(ep);

// Allowed
obj.walk();
obj.bar.jump();
console.log(await obj.bar.name);

// Not allowed
obj.walk.toString();
obj.bar.jump.foo = 1;
await obj.bar.name.__proto__;

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.

1 participant