Hello.
I’d like to execute code from content scripts in background script context. Is it ok to use something like https://www.npmjs.com/package/comlink for this or it is not allowed?
Thanks.
Hello.
I’d like to execute code from content scripts in background script context. Is it ok to use something like https://www.npmjs.com/package/comlink for this or it is not allowed?
Thanks.
Have you tried it yet?
The available API in the content scripts is quite limited, usually nothing fancy works, and this looks quite fancy .
Also, it’s forbidden to execute remote code - that is executing a code that’s not part of the addon:
Practically, regarding content scripts, if you want to execute some job in the background script, you use something like this:
const dataToSend = {foo: 'bar'};
const result = await browser.runtime.sendMessage({type: 'content_script_job', data: dataToSend});
console.log('background computed result:', result);
So sending a data to the background script, which then processes them and sends result - by returning a Promise in the https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage handler.
Thanks for your reply!
So, as long as all code is included within extension, it is allowed?
Regarding your example, I already have it done like this, but I thought it would be more convenient for development to do it with something like the library mentioned.
For clarity, comlink does not execute arbitrary code across contexts. Rather, it lets you work directly with simple objects and under the hood it passess messages between contexts. Critically, though, all the code executed on either side of the message passing system is statically defined in your scripts.
That said, I still haven’t spent the time to get a functional example of comlink or clooney working in a browser extension.
I just thought that if some APIs are not available in content script’s context, maybe this was intended as a security measure, so if content script is compromised (somehow) it still can’t do a lot of destructive things.
So, if you expose background script’s window object to a content script, it basically prevents this security measure.
You are correct that content scripts have limited extension API access for security reasons. To oversimplify a bit, browsers spread work across multiple processes in order to minimize the risk associated with any one process becoming compromised. Since an extension’s content script is executed in the same process as a given website, a compromised website would also be able to exploit any privileged capabilities exposed to a content script on that site.
That said, I don’t follow what you mean when you say “if you expose background script’s window object to a content script…”. I agree that would be concerning, but I don’t see how you would do that or how comlink facilitates that process. To the best of my knowledge, comlink just provides a nicer API for passing data between contexts using the platform’s underlying messaging APIs.
I mean, if you can do something like Comlink.expose(window), then you can call any function available in that window’s context.
So, in my case, if i do Comlink.expose(window) in the background script and then access it from content script, content script will be able to invoke any functionality that background script has access to.
That said, I’m not planning to use comlink specifically, I just gave it as an example, so, sorry if I don’t understand how comlink actually works.
I don’t know for sure that I understand how comlink works, so we’re all good
I hadn’t considered the possibility of calling Comlink.expose(window)
. Now that you’ve called it out, I agree that this both seems possible and like a serious security risk.
Just to emphasize, you should treat messages from content scripts as if they were generated by an untrusted source because, well, they could be. I’ve seen scenarios where good developers make a mistake and end up accepting accidentally allowing the page to send arbitrary messages to the extension’s background page.