Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Talk about code development, features, specific bugs, enhancements, patches, and similar things.
Forum rules
Please keep everything here strictly on-topic.
This board is meant for Pale Moon source code development related subjects only like code snippets, patches, specific bugs, git, the repositories, etc.

This is not for tech support! Please do not post tech support questions in the "Development" board!
Please make sure not to use this board for support questions. Please post issues with specific websites, extensions, etc. in the relevant boards for those topics.

Please keep things on-topic as this forum will be used for reference for Pale Moon development. Expect topics that aren't relevant as such to be moved or deleted.
User avatar
AstuteAnalyst
Newbie
Newbie
Posts: 6
Joined: 2024-06-21, 21:51

Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by AstuteAnalyst » 2024-06-21, 22:39

I'm the main author of a JS sandboxing library that works fairly well across browsers (i.e., Blink, Gecko and WebKit). However, when testing on Pale Moon, I noticed an issue that prevents it for working. In the browser, sandboxing can be done in various ways (talking in general, but also about the library). The first way is using pure JS (bare), then putting the code into a Worker (worker). So far, these strategies work fine.

However, there's two additional strategies, running inside an <iframe> (browser-window) or running a Worker inside an <iframe> (browser-worker). The reason to do this is that a Worker by itself cannot have a different CSP than the parent, but using a frame allows this. It also allows sandboxing in scenarios where workers are disabled but frames aren't.

It appears that, when an <iframe> is involved, the library fails. This is disappointing as I was recently working on a utility to encrypt files and showcase sandboxing that would like to have as wide compatibility as possible.

The error that I get, 'Timed out setting up sandbox', without anything else, would seem to indicate an error while setting things up, possibly preventing the iframe script from executing, although the debugger doesn't seem to show anything is amiss.

The following is a snippet that can be run in the console to test.

Code: Select all

// Strategy: iframe + Worker with 'just' iframe fallback
(async ()=>await (await (await import('https://esm.sh/@exact-realty/lot')).default('exports.foo="bar"'))('foo'))().then((r) => console.log('ok', r), (e) => console.error('err', e));
// Result: error

Code: Select all

// Strategy: bare
(async ()=>await (await (await import('https://esm.sh/@exact-realty/lot/bare')).default('exports.foo="bar"'))('foo'))().then((r) => console.log('ok', r), (e) => console.error('err', e));
// Result: ok

Code: Select all

// Strategy: Worker
(async ()=>await (await (await import('https://esm.sh/@exact-realty/lot/worker')).default('exports.foo="bar"'))('foo'))().then((r) => console.log('ok', r), (e) => console.error('err', e));
// Result: ok

Code: Select all

// Strategy: iframe + Worker
(async ()=>await (await (await import('https://esm.sh/@exact-realty/lot/browser-worker')).default('exports.foo="bar"'))('foo'))().then((r) => console.log('ok', r), (e) => console.error('err', e));
// Result: error

Code: Select all

// Strategy: iframe
(async ()=>await (await (await import('https://esm.sh/@exact-realty/lot/browser-window')).default('exports.foo="bar"'))('foo'))().then((r) => console.log('ok', r), (e) => console.error('err', e));
// Result: error

All of the snippets work well on Firefox. I can also provide an example site that's broken because of this, although the snippets above should be enough to reproduce the issue. I'm happy to help providing more information and testing.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 37634
Joined: 2011-08-28, 17:27
Location: Motala, SE

Re: Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by Moonchild » 2024-06-21, 22:48

Since you're the main author, can you please tell us exactly how you've set this up? What combination of code is being used here in each instance (HTML + CSP + JS)? Reverse-engineering that from practical examples, although those are good to be able to test, isn't exactly a useful way to spend time when you have it all directly available to tell us.

User avatar
AstuteAnalyst
Newbie
Newbie
Posts: 6
Joined: 2024-06-21, 21:51

Re: Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by AstuteAnalyst » 2024-06-21, 22:59

I agree. I'm working on a minimal example that I can post and that should greatly narrow down the issue.

User avatar
AstuteAnalyst
Newbie
Newbie
Posts: 6
Joined: 2024-06-21, 21:51

Re: Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by AstuteAnalyst » 2024-06-22, 03:45

After some investigation, I could significantly narrow down where the failure happens, at least the first one (if there are many, which I'm hoping there aren't).

The steps go more or less as follows.
  • Main document creates an iframe with certain content (using a blob: URL)
  • Iframe sends a message to main document saying it's ready
  • Main document sends a message to the iframe with init options
  • Iframe sets sandbox up and signals that it's ready
Well, it turns out that this sequence is disrupted because, for the very first message, the main document checks whether the message comes from a trusted origin (e.isTrusted). This is, apparently, false where true is expected, and as a result the rest of the sequence doesn't proceed.

Tomorrow, I might try the whole sandbox library without this particular check at this particular location and see if the rest of things look fine. However, the `isTrusted` behaviour there is different from what both Chrome and Firefox do in this case (the event is trusted because it's using `postMessage` instead of `dispatchEvent`).

The attached tarball includes a simplified version of the bootstrap script that reproduces the failure in Pale Moon and works in Firefox.
You do not have the required permissions to view the files attached to this post.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 37634
Joined: 2011-08-28, 17:27
Location: Motala, SE

Re: Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by Moonchild » 2024-06-22, 08:54

Right, I think I know what's going on. Thanks for explaining in detail what your analysis is so far.

Initially, these mechanisms (BroadcastChannel and MessagePort) implicitly called for dispatched events to not be trusted, but since browsers (notably Chrome... because it went by which mechanism fired the event instead of creating the event) marked them as trusted.
Of course Gecko eventually followed Chrome's behaviour (as it always does because Google pays their bills) so eventually, the spec for this was changed to make them trusted in this case. We should follow suit to align with expected browser behaviour.

Edit: Filed Issue #2534 (UXP)

User avatar
AstuteAnalyst
Newbie
Newbie
Posts: 6
Joined: 2024-06-21, 21:51

Re: Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by AstuteAnalyst » 2024-06-22, 13:57

I've tried a build of the entire library with iframe isTrusted checks disabled (it's only two messages in this case, the rest use MessagePort) and things look like they work, so maybe it was just this one issue.

Thanks for the reply and the background! It's probably a good idea to have consistent behaviour across browsers, and, although here I wasn't aware that this was a Chrome innovation, I think it's one that makes sense (otherwise, message events would always be 'untrusted', at which point the isTrusted attribute isn't very useful), because distinguishing by mechanism is meaningful (i.e., you can tell the message came from the right source).

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 37634
Joined: 2011-08-28, 17:27
Location: Motala, SE

Re: Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by Moonchild » 2024-06-22, 14:03

AstuteAnalyst wrote:
2024-06-22, 13:57
I think it's one that makes sense (otherwise, message events would always be 'untrusted', at which point the isTrusted attribute isn't very useful), because distinguishing by mechanism is meaningful
It's a nuance difference. The original spec (and our current behaviour) requires that the caller is trusted for the event to be trusted (IIUC). So it would not be useless to have, at all. In fact, one could easily see that in the current (Chrome) situation the isTrusted property is a bit less useful than in its original design, but it just boils down to what it was designed to do how one can use it.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 37634
Joined: 2011-08-28, 17:27
Location: Motala, SE

Re: Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by Moonchild » 2024-06-23, 16:10

Verified my patch with the simplified bootstrap script. Thanks for supplying it for quick QE!

User avatar
AstuteAnalyst
Newbie
Newbie
Posts: 6
Joined: 2024-06-21, 21:51

Re: Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by AstuteAnalyst » 2024-06-25, 22:01

Glad to hear that it helped! Once it makes it to a release, I'll test again.

User avatar
AstuteAnalyst
Newbie
Newbie
Posts: 6
Joined: 2024-06-21, 21:51

Re: Issue with JS Sandboxing Library - iframe-Related Strategies Fail

Unread post by AstuteAnalyst » 2024-11-25, 00:11

I just wanted to report that I tested this and it seems to work well. Thanks for the quick fix.