Open Bug 1906040 Opened 7 months ago Updated 2 months ago

Security Error: Content at http://localhost:xxxx/ may not load data from blob:http://localhost:xxxx/... when assigning blob url of MediaSource

Categories

(Core :: Audio/Video: Playback, defect)

Firefox 127
Desktop
macOS
defect

Tracking

()

REOPENED

People

(Reporter: andrea, Unassigned)

References

(Blocks 1 open bug)

Details

Steps to reproduce:

I currently have a setup to emulate Web Workers support when some functionalities are not supported on different browsers in order to use the same messaging system across all browsers. In this case Firefox does not support Media Source Extension in a Web Worker. When in "no-worker" mode I create a MessageChannel and exchange messages between the "worker" thread and the main thread using the MessageChannel ports. This is how my code looks like overall:

// on the worker side
postMessageToMain("createVideo")
const mediaSource = new MediaSource()
if (workerSupported){
  const handle = mediaSource.handle
  postMessageToMain("setSource", handle, [handle])
} else {
  const handle = URL.createObjectURL(mediaSource)
  postMessageToMain("setSource", handle)
}

// on the main thread
onmessage(m){
  switch (m) {
    case "createVideo":{
        videoElement = document.createElement('video')
        videoElement.playsInline = true
        break
    }
    case "setSource":{
        if(workerSupported){
         videoElement.srcObject = m.data.handle // it is of type MediaSourceHandle
        } else {
         videoElement.src = m.data.handle // is of type string, here the error in the title is thrown
        }
    }
  }
}

This code works on Chrome in worker and non-worker mode while on safari, given that MSE in Web Worker is not supported, works only in non-worker mode. I'm NOT setting any CSP header. Am i doing something wrong?

Actual results:

As soon as i assign the blob url generated by URL.createObjectURL(mediaSource) to the video src , i get the following Security Error
Security Error: Content at http://localhost:xxxx/ may not load data from blob:http://localhost:xxxx/... when assigning blob url of MediaSource

Expected results:

No error when assigning the blob url

OS: Unspecified → macOS
Hardware: Unspecified → Desktop

The Bugbug bot thinks this bug should belong to the 'Core::DOM: Workers' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → DOM: Workers
Product: Firefox → Core

To be more clear about the bug:
The above code on Firefox runs entirely on the main thread.
// on the worker side simply indicates in a "Web Workers not supported scenario" that it is code executed on the other side of the MessageChannel

Component: DOM: Workers → Audio/Video: Playback

The severity field is not set for this bug.
:jimm, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(jmathies)

Here's a minimal reproducible example: https://stackblitz.com/edit/vitejs-vite-hxbktr?file=main.js

After debugging it seems that the culprit is the MessageChannel, maybe the MediaSource goes out of scope after sending the message, gets garbage collected and triggers the security error when trying to use it

A workaround for this issue seems to keep a reference of the MediaSource on the window object. Something like window.mysource = new MediaSource() does the trick.

I can repro the issue on macOS, going back as far as M86, so this is probably not a regression.
The culprit seems to be that the reference of the blob: URL is revoked when said blob: URL isn't consumed immediately. A more minimal test case can be seen at https://jsfiddle.net/kzgvpu79

const video = document.querySelector('video');
window.mediaSource = new MediaSource();
const url = URL.createObjectURL(mediaSource);
setTimeout(() => { // <-- this timeout is the actual culprit
  video.src = url;
});

Consuming the URL directly would avoid the bug: https://jsfiddle.net/kzgvpu79/1/ & https://jsfiddle.net/kzgvpu79/2/

On my side however keeping a global reference to the MediaSource object doesn't work, contrarily to what is stated in comment 5.

Interesting! Thank you for providing an even simpler example. I thought it was the MediaSource object going out of scope because i tried first keeping a reference to the blob url on the window object but with no luck:

const source = MediaSource()
window.myurl = URL.createObjectURL(source);

// async stuff happens (message passing in the Message Channel)

video.src = window.myurl <-- This fails

Now i understand why it didn't work, because i wasn't consuming the url immediately :)
Keeping a reference of the MediaSource on the window object worked on my case because i ended up doing this:

window.mysource = MediaSource()

// async stuff happens (message passing in the Message Channel)

const url = URL.createObjectURL(window.mysource)
video.src = url <-- This works
See Also: → 1852453
Flags: needinfo?(jmathies)
Status: UNCONFIRMED → RESOLVED
Closed: 5 months ago
Resolution: --- → WORKSFORME

This is still an issue on Firefox 133 on MacOS as seen with https://jsfiddle.net/kzgvpu79

Flags: needinfo?(jmathies)
Blocks: media-triage
Status: RESOLVED → REOPENED
Ever confirmed: true
Flags: needinfo?(jmathies)
Resolution: WORKSFORME → ---
You need to log in before you can comment on or make changes to this bug.