Q120: every IPC call passes one gate - the app's own page, input checked against a typed contract

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-08 19:25:32 -04:00
1 parent 43591d4c99
commit 04c8cce0c4
10 files changed
+435 -103

No files matched your search

+14 -3
View File
@@ -1,10 +1,21 @@
import type { BrowserWindow } from "electron";
import { fileURLToPath } from "node:url";
export function attachMainWindowSecurity(win: BrowserWindow, devServerOrigin: string | null): void {
/** Whether a URL is the app's own page: the exact index.html it was built with, or any route of the dev server it is served by. */
export function isAppPage(url: string, appPage: string): boolean {
if (!URL.canParse(url)) return false;
const target = new URL(url);
const page = new URL(appPage);
if (page.protocol !== "file:") return target.origin === page.origin;
if (target.protocol !== "file:") return false;
const path = (value: URL): string => (process.platform === "win32" ? fileURLToPath(value).toLowerCase() : fileURLToPath(value));
return path(target) === path(page);
}
export function attachMainWindowSecurity(win: BrowserWindow, appPage: string): void {
win.webContents.setWindowOpenHandler(() => ({ action: "deny" }));
const blockNavigation = (event: Electron.Event, url: string): void => {
if (devServerOrigin && url.startsWith(devServerOrigin)) return;
if (url.startsWith("file://")) return;
if (isAppPage(url, appPage)) return;
event.preventDefault();
};
win.webContents.on("will-navigate", blockNavigation);