fix(core): authenticate runtime control message senders (#3813)

This commit is contained in:
James Russo
2026-09-09 10:26:56 -04:00
committed by GitHub
parent 4f77c282da
commit b8328f9573
3 changed files with 53 additions and 0 deletions
+43
View File
@@ -27,11 +27,54 @@ function createMockDeps() {
function makeControlMessage(action: string, extra?: Record<string, unknown>) {
return new MessageEvent("message", {
source: window.parent,
data: { source: "hf-parent", type: "control", action, ...extra },
});
}
describe("installRuntimeControlBridge", () => {
it("rejects foreign and null senders before dispatching controls", () => {
const foreign = document.createElement("iframe");
document.body.append(foreign);
const deps = createMockDeps();
const handler = installRuntimeControlBridge(deps);
try {
for (const source of [foreign.contentWindow, null]) {
handler(
new MessageEvent("message", {
source,
data: { source: "hf-parent", type: "control", action: "play" },
}),
);
}
expect(deps.onPlay).not.toHaveBeenCalled();
handler(
new MessageEvent("message", {
source: window,
data: { source: "hf-parent", type: "control", action: "play" },
}),
);
expect(deps.onPlay).toHaveBeenCalledOnce();
} finally {
window.removeEventListener("message", handler);
foreign.remove();
}
});
it("accepts an embedding parent distinct from the runtime window", () => {
const frame = document.createElement("iframe");
document.body.append(frame);
vi.stubGlobal("parent", frame.contentWindow);
const deps = createMockDeps();
const handler = installRuntimeControlBridge(deps);
try {
handler(makeControlMessage("play"));
expect(deps.onPlay).toHaveBeenCalledOnce();
} finally {
window.removeEventListener("message", handler);
vi.unstubAllGlobals();
frame.remove();
}
});
it("dispatches play command", () => {
const deps = createMockDeps();
const handler = installRuntimeControlBridge(deps);
+1
View File
@@ -123,6 +123,7 @@ function handleFlashElements(data: BridgeControlData): void {
export function installRuntimeControlBridge(deps: BridgeDeps): (event: MessageEvent) => void {
const handler = (event: MessageEvent) => {
if (event.source !== window.parent && event.source !== window) return;
const data = event.data as BridgeControlData | null;
if (!data || data.source !== "hf-parent" || data.type !== "control") return;
if (rejectUnsupportedProtocol(data)) return;
+9
View File
@@ -169,6 +169,7 @@ describe("initSandboxRuntimeModular", () => {
window.dispatchEvent(
new MessageEvent("message", {
source: window.parent,
data: { source: "hf-parent", type: "control", action: "set-volume", volume: 1 },
}),
);
@@ -239,6 +240,7 @@ describe("initSandboxRuntimeModular", () => {
window.addEventListener("error", onError);
window.dispatchEvent(
new MessageEvent("message", {
source: window.parent,
data: { source: "hf-parent", type: "control", action: "set-volume", volume: 1 },
}),
);
@@ -2846,6 +2848,7 @@ describe("initSandboxRuntimeModular", () => {
if (payload.source !== "hf-preview" || payload.type !== "ready") return;
window.dispatchEvent(
new MessageEvent("message", {
source: window.parent,
data: {
source: "hf-parent",
type: "control",
@@ -2856,6 +2859,7 @@ describe("initSandboxRuntimeModular", () => {
);
window.dispatchEvent(
new MessageEvent("message", {
source: window.parent,
data: {
source: "hf-parent",
type: "control",
@@ -3049,6 +3053,7 @@ describe("initSandboxRuntimeModular", () => {
window.dispatchEvent(
new MessageEvent("message", {
source: window.parent,
data: { source: "hf-parent", type: "control", action: "set-muted", muted: false },
}),
);
@@ -3058,6 +3063,7 @@ describe("initSandboxRuntimeModular", () => {
window.dispatchEvent(
new MessageEvent("message", {
source: window.parent,
data: { source: "hf-parent", type: "control", action: "set-muted", muted: true },
}),
);
@@ -3067,6 +3073,7 @@ describe("initSandboxRuntimeModular", () => {
window.dispatchEvent(
new MessageEvent("message", {
source: window.parent,
data: { source: "hf-parent", type: "control", action: "set-muted", muted: false },
}),
);
@@ -3100,6 +3107,7 @@ describe("initSandboxRuntimeModular", () => {
window.dispatchEvent(
new MessageEvent("message", {
source: window.parent,
data: {
source: "hf-parent",
type: "control",
@@ -3148,6 +3156,7 @@ describe("initSandboxRuntimeModular", () => {
window.dispatchEvent(
new MessageEvent("message", {
source: window.parent,
data: {
source: "hf-parent",
type: "control",