diff --git a/frontend/webcomponent/src/components/CommandsManager.ts b/frontend/webcomponent/src/components/CommandsManager.ts index fdc36a7..c128f98 100644 --- a/frontend/webcomponent/src/components/CommandsManager.ts +++ b/frontend/webcomponent/src/components/CommandsManager.ts @@ -11,7 +11,15 @@ import { InboundCommandMessage } from '../models/message.type'; */ export class CommandsManager { private iframe: HTMLIFrameElement; - private allowedOrigin: string; + /** + * The origin of the iframe content that messages will be sent to. + * Used as the 'targetOrigin' parameter in postMessage calls. + * Initially set to '*' (insecure) until the actual iframe URL is loaded. + * + * SECURITY NOTE: The value '*' should be replaced with the actual origin + * as soon as possible using setTargetOrigin(). + */ + private targetIframeOrigin: string; /** * A map to store event handlers for different events. * This allows for dynamic event handling and can be used to add or remove event listeners. @@ -21,9 +29,15 @@ export class CommandsManager { */ private eventHandlers: Map> = new Map(); - constructor(iframe: HTMLIFrameElement, allowedOrigin: string) { + /** + * Creates a new CommandsManager instance + * + * @param iframe - The iframe element used for communication + * @param initialTargetOrigin - The initial target origin for postMessage + */ + constructor(iframe: HTMLIFrameElement, initialTargetOrigin: string) { this.iframe = iframe; - this.allowedOrigin = allowedOrigin; + this.targetIframeOrigin = initialTargetOrigin; } /** @@ -148,16 +162,24 @@ export class CommandsManager { // } /** - * Sets the allowed origin for the current instance. + * Updates the target origin used when sending messages to the iframe. + * This should be called once the iframe URL is known to improve security. * - * @param newOrigin - The new origin to be set as allowed. + * @param newOrigin - The origin of the content loaded in the iframe + * (e.g. 'https://meet.example.com') */ - public setAllowedOrigin(newOrigin: string): void { - this.allowedOrigin = newOrigin; + public setTargetOrigin(newOrigin: string): void { + this.targetIframeOrigin = newOrigin; } - private sendMessage(message: InboundCommandMessage, targetOrigin?: string): void { - targetOrigin = targetOrigin || this.allowedOrigin; - this.iframe.contentWindow?.postMessage(message, targetOrigin); + /** + * Sends a message to the iframe using window.postMessage + * + * @param message - The message to send to the iframe + * @param explicitTargetOrigin - Optional override for the target origin + */ + private sendMessage(message: InboundCommandMessage, explicitTargetOrigin?: string): void { + explicitTargetOrigin = explicitTargetOrigin || this.targetIframeOrigin; + this.iframe.contentWindow?.postMessage(message, explicitTargetOrigin); } } diff --git a/frontend/webcomponent/src/components/OpenViduMeet.ts b/frontend/webcomponent/src/components/OpenViduMeet.ts index e3156b1..c62298f 100644 --- a/frontend/webcomponent/src/components/OpenViduMeet.ts +++ b/frontend/webcomponent/src/components/OpenViduMeet.ts @@ -1,5 +1,3 @@ -import { WebComponentCommand } from '../models/command.model'; -import { InboundCommandMessage } from '../models/message.type'; import { CommandsManager } from './CommandsManager'; import { EventsManager } from './EventsManager'; import styles from '../assets/css/styles.css'; @@ -30,7 +28,7 @@ export class OpenViduMeet extends HTMLElement { private commandsManager: CommandsManager; private eventsManager: EventsManager; //!FIXME: Insecure by default - private allowedOrigin: string = '*'; + private targetIframeOrigin: string = '*'; private loadTimeout: any; private iframeLoaded = false; private errorMessage: string | null = null; @@ -44,7 +42,7 @@ export class OpenViduMeet extends HTMLElement { 'camera; microphone; display-capture; fullscreen; autoplay; compute-pressure;' ); - this.commandsManager = new CommandsManager(this.iframe, this.allowedOrigin); + this.commandsManager = new CommandsManager(this.iframe, this.targetIframeOrigin); this.eventsManager = new EventsManager(this); // Listen for changes in attributes to update the iframe src @@ -140,8 +138,8 @@ export class OpenViduMeet extends HTMLElement { } const url = new URL(baseUrl); - this.allowedOrigin = url.origin; - this.commandsManager.setAllowedOrigin(this.allowedOrigin); + this.targetIframeOrigin = url.origin; + this.commandsManager.setTargetOrigin(this.targetIframeOrigin); // Update query params Array.from(this.attributes).forEach((attr) => {