Commit 905077aa authored by Robert Knight's avatar Robert Knight

Handle port requests from guests with opaque origins

When a guest frame with an opaque origin, such as file:// URL or a sandboxed
iframe, sends a request for a port to the host frame, the `event.origin` value
will be the string "null". This is not a legal value for the `targetOrigin`
argument to `postMessage`, so we need to remap it to "*" (any origin).
parent a9ce9227
...@@ -192,7 +192,16 @@ export class PortProvider { ...@@ -192,7 +192,16 @@ export class PortProvider {
: new MessageChannel(); : new MessageChannel();
const message = { frame1, frame2, type: 'offer' }; const message = { frame1, frame2, type: 'offer' };
source.postMessage(message, origin, [messageChannel.port1]);
// If the source window has an opaque origin [1], `event.origin` will be
// the string "null". This is not a legal value for the `targetOrigin`
// parameter to `postMessage`, so remap it to "*".
//
// [1] https://html.spec.whatwg.org/multipage/origin.html#origin.
// Documents with opaque origins include file:// URLs and
// sandboxed iframes.
const targetOrigin = origin === 'null' ? '*' : origin;
source.postMessage(message, targetOrigin, [messageChannel.port1]);
if (frame2 === 'sidebar') { if (frame2 === 'sidebar') {
this._sidebarHostChannel.port2.postMessage(message, [ this._sidebarHostChannel.port2.postMessage(message, [
......
...@@ -135,6 +135,7 @@ describe('PortProvider', () => { ...@@ -135,6 +135,7 @@ describe('PortProvider', () => {
frame2: 'host', frame2: 'host',
type: 'request', type: 'request',
}; };
await sendPortFinderRequest({ await sendPortFinderRequest({
data, data,
}); });
...@@ -147,6 +148,21 @@ describe('PortProvider', () => { ...@@ -147,6 +148,21 @@ describe('PortProvider', () => {
); );
}); });
it('responds to a valid port request from a source with an opaque origin', async () => {
portProvider.listen();
const data = {
frame1: 'guest',
frame2: 'sidebar',
type: 'request',
};
await sendPortFinderRequest({ data, origin: 'null' });
assert.calledWith(window.postMessage, { ...data, type: 'offer' }, '*', [
sinon.match.instanceOf(MessagePort),
]);
});
it('responds to the first valid port request but ignores additional requests', async () => { it('responds to the first valid port request but ignores additional requests', async () => {
portProvider.listen(); portProvider.listen();
const data = { const data = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment