GoogleChromeLabs / comlink

Comlink makes WebWorkers enjoyable.
Apache License 2.0
11.26k stars 386 forks source link

Is secure communication possible when using comlink with iframes? #444

Open EliBlitz opened 4 years ago

EliBlitz commented 4 years ago

Hey, I was about to use this awesome library in one of my projects. In this project I want to allow apps running in cross-domain iframes to activate functionalities in the top frame. For this to work I exposed services on the top window, and in the iframe I used wrap in order to consume the activation API. This, however, brings up a troubling security issue. The exposed functionality on the top window is now exposed to any attacker who wishes to activate tasks in my app. Even if I guard myself from sending data by supplying a targetOrigin parameter in the top window, this only protects against outgoing messages but does not allow me to verify that I am accepting incoming messages only from my apps. I read through the code and did not find this kind of validation on incoming messages. Did I miss anything? Is there currently a way to secure myself when using the window as an endpoint?

Thanks.

surma commented 4 years ago

No, that’s actually correct, I currently don’t offer any way to validate the incoming origin. I should add that :)

EliBlitz commented 4 years ago

Thank you for your answer :)

sdoomz commented 2 years ago

this only protects against outgoing messages but does not allow me to verify that I am accepting incoming messages only from my apps

I think you may overcome this with MessageChannels, so instead of exposing APIs to the mainframe you could expose it the port1 returned from new MessageChannnel(). Afterwards, you take port2 and send it with a post message to the frame you want to establish communication with, an iframe waits for a message, takes port2 and uses Comlink.wrap(port2) to obtain an API exposed on the main frame.

dwabyick commented 1 year ago

FYI - I was thinking about using comlink for a cross-origin iframe-communication feature, but noticed the same thing - there is no way to validate the origin on incoming messages coming through.

It seems like it would have to be baked into the actual communication protocol, vs. getting exposed to wrapped functions, for the cleanest API.

mhofman commented 1 year ago

As @sdoomz mentions, only the initial message transfer needs to be origin validated when bootstrapping MessageChannels, which can be done at the application level. All subsequent exchanges can happen over this prevalidated channel.

benjamind commented 1 year ago

605 adds a simple origin filter on the expose function to support this now. Will close this ticket once the new version is published.