Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/guide/client/using-a-proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ A valid proxy script must:
2. **Validate the URL**: It must validate that the provided URL is a valid `http:` or `https:` URL to prevent abuse.
3. **Render in an Iframe**: The script should dynamically create an iframe and set its `src` to the validated target URL.
4. **Sandbox the Iframe**: The iframe must be sandboxed to restrict its capabilities. A minimal sandbox policy would be `allow-scripts allow-same-origin`.
5. **Forward `postMessage` Events**: To allow communication between the host application and the embedded external URL, the proxy needs to forward `message` events between `window.parent` and the iframe's `contentWindow`.
5. **Forward `postMessage` Events**: To allow communication between the host application and the embedded external URL, the proxy needs to forward `message` events between `window.parent` and the iframe's `contentWindow`. For security, it's critical to use a specific `targetOrigin` instead of `*` in `postMessage` calls whenever possible. The `targetOrigin` for messages to the iframe should be the external URL's origin; Messages to the parent will resort to `*`.

### Example Self-Hosted Proxy

Expand Down
15 changes: 8 additions & 7 deletions packages/client/scripts/proxy/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
try {
const url = new URL(string);
return url.protocol === 'http:' || url.protocol === 'https:';
} catch (_) {
} catch (error) {
return false;
}
}
Expand All @@ -50,14 +50,15 @@
inner.style = 'width:100%; height:100%; border:none;';
inner.sandbox = 'allow-same-origin allow-scripts';
document.body.appendChild(inner);
const urlOrigin = new URL(target).origin;

window.addEventListener('message', (event) => {
// listen for messages from the iframe and send them to the parent
if (event.source === inner.contentWindow) {
window.parent.postMessage(event.data, '*');
}
// listen for messages from the parent and send them to the iframe
if (event.source === window.parent) {
inner.contentWindow.postMessage(event.data, '*');
// listen for messages from the parent and send them to the iframe
inner.contentWindow.postMessage(event.data, urlOrigin);
} else if (event.source === inner.contentWindow) {
// listen for messages from the iframe and send them to the parent
window.parent.postMessage(event.data, '*');
}
});
}
Expand Down