w3c / webextensions

Charter and administrivia for the WebExtensions Community Group (WECG)
Other
576 stars 50 forks source link

Allow to create sandboxed iframes in background script of addons #637

Open vitonsky opened 2 weeks ago

vitonsky commented 2 weeks ago

I've just filed bug report, because i didn't found any info about this problem, so i'm not sure it is bug or a lack of functionality, so i create issue here too.

Introduction

As developer of browser addon for translate web pages i need a way to run user code in sandboxed environment. This feature is necessary for cases like custom translators, since user may insert a code that will be evaluated by addon, to let user implement custom logic for fetching any API for translation (even locally deployed machine translation with REST API or something like ChatGPT).

However, the problem here is currently not possible to sandbox the code and it is possible to run code only in background context, which is potentially dangerous, because user script may have access to whole addon API.

The problem may be solved by run the code in some limited environment. For chrome it is possible to create a sandboxed iframe that will evaluate the code and return only translated text with messaging through postMessage.

When i tried to implement a similar logic with Firefox, i had a problem - iframe is empty:

2024-06-12_00-26_1 2024-06-12_00-26

hence any JS code for manage code evaluation in sandbox can't be runned.

Only options available for me currently is:

Proposal

Allow to run iframes with pages from addon bundle in background page of addon

fregante commented 2 weeks ago

This is definitely possible in Chrome MV2, so if it doesn't work on Firefox then the bug report is more appropriate.

In MV3 this is currently possible via offscreen document, I doubt that they will add a way to create iframes in the service worker. Unfortunately this means you need to first open the offscreen document and then create a sandboxed iframe in it.

vitonsky commented 2 weeks ago

This is definitely possible in Chrome MV2, so if it doesn't work on Firefox then the bug report is more appropriate.

In MV3 this is currently possible via offscreen document, I doubt that they will add a way to create iframes in the service worker. Unfortunately this means you need to first open the offscreen document and then create a sandboxed iframe in it.

I just checked, it looks it is possible to create iframe in firefox if a bit change the commands and first add a created iframe element to document and then change it src like that:

const iframe = document.createElement('iframe', {});
iframe.setAttribute(
  'sandbox',
  'allow-same-origin allow-scripts allow-popups allow-forms',
);
document.body.appendChild(iframe);
iframe.src = '/offscreen-documents/translator/translator.html';

so the problem with empty iframe is solved with swap last 2 lines. However we still have a problem with sandboxing in manifest v3.

Firefox currently does not support offscreen API nor sandbox feature in manifest declaration. It only supports background script where i may append iframe, but this iframe cannot to run eval with no any way. This is because i can't allow unsafe-eval CSP since it is disallowed in manifest v3 and allowed only in sandbox (that is not exists in firefox).

Rob--W commented 2 weeks ago

Firefox doesn't support the manifest sandbox key yet: https://bugzilla.mozilla.org/show_bug.cgi?id=1685123 Safari doesn't either.

Chrome requires a service worker, which doesn't support DOM and can therefore not directly load iframes. They do however offer the offscreen API from which you can use DOM, and in turn create a sandboxed iframe.

I just checked, it looks it is possible to create iframe in firefox if a bit change the commands and first add a created iframe element to document and then change it src like that:

iframe.setAttribute(
  'sandbox',
  'allow-same-origin allow-scripts allow-popups allow-forms',
);

Warning: This is not an effective sandbox at all. allow-same-origin allow-scripts means that code can execute in the "sandboxed" iframe and that it can reach into the parent document (due to allow-same-origin).

rdcronin commented 16 hours ago

Since Chrome doesn't support background pages, this is irrelevant for Chrome. Removing the Chrome triage label.