Skip to content

Commit 507fbbf

Browse files
committed
fix(sandbox): add origin validation for host messages
The sandbox proxy now validates that messages from the parent window come from the expected host origin (derived from document.referrer). This prevents malicious pages from sending spoofed messages to the sandbox. Changes: - Extract EXPECTED_HOST_ORIGIN from document.referrer - Validate event.origin against expected origin for parent messages - Use specific origin instead of '*' when sending to parent - Reject and log messages from unexpected origins This addresses the TODO comment that was previously in the code.
1 parent e3c01ae commit 507fbbf

1 file changed

Lines changed: 20 additions & 4 deletions

File tree

examples/basic-host/src/sandbox.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ if (!document.referrer.match(ALLOWED_REFERRER_PATTERN)) {
1616
);
1717
}
1818

19+
// Extract the expected host origin from the referrer for origin validation.
20+
// This is the origin we expect all parent messages to come from.
21+
const EXPECTED_HOST_ORIGIN = new URL(document.referrer).origin;
22+
1923
// Security self-test: verify iframe isolation is working correctly.
2024
// This MUST throw a SecurityError -- if `window.top` is accessible, the sandbox
2125
// configuration is dangerously broken and untrusted content could escape.
@@ -79,8 +83,18 @@ function buildCspMetaTag(csp?: { connectDomains?: string[]; resourceDomains?: st
7983

8084
window.addEventListener("message", async (event) => {
8185
if (event.source === window.parent) {
82-
// NOTE: In production you'll also want to validate `event.origin` against
83-
// your Host domain.
86+
// Validate that messages from parent come from the expected host origin.
87+
// This prevents malicious pages from sending messages to this sandbox.
88+
if (event.origin !== EXPECTED_HOST_ORIGIN) {
89+
console.error(
90+
"[Sandbox] Rejecting message from unexpected origin:",
91+
event.origin,
92+
"expected:",
93+
EXPECTED_HOST_ORIGIN
94+
);
95+
return;
96+
}
97+
8498
if (event.data && event.data.method === RESOURCE_READY_NOTIFICATION) {
8599
const { html, sandbox, csp } = event.data.params;
86100
if (typeof sandbox === "string") {
@@ -113,13 +127,15 @@ window.addEventListener("message", async (event) => {
113127
}
114128
} else if (event.source === inner.contentWindow) {
115129
// Relay messages from inner frame to parent window.
116-
window.parent.postMessage(event.data, "*");
130+
// Use specific origin instead of "*" to prevent message interception.
131+
window.parent.postMessage(event.data, EXPECTED_HOST_ORIGIN);
117132
}
118133
});
119134

120135
// Notify the Host that the Sandbox is ready to receive Guest UI HTML.
136+
// Use specific origin instead of "*" to ensure only the expected host receives this.
121137
window.parent.postMessage({
122138
jsonrpc: "2.0",
123139
method: PROXY_READY_NOTIFICATION,
124140
params: {},
125-
}, "*");
141+
}, EXPECTED_HOST_ORIGIN);

0 commit comments

Comments
 (0)