Harden render server and import boundaries

This commit is contained in:
th committed 2026-06-05 20:05:32 +02:00
1 parent 5cc373cf6b
commit fae55e3f13
11 files changed
+2400 -54

No files matched your search

+26 -3
View File
@@ -1,9 +1,11 @@
import { app, BrowserWindow, Menu, shell } from 'electron'
import type { BrowserWindow as BrowserWindowInstance, Event, MenuItemConstructorOptions } from 'electron'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const isDev = !app.isPackaged
const devServerUrl = process.env.VITE_DEV_SERVER_URL ?? 'http://localhost:5200'
const devServerOrigin = new URL(devServerUrl).origin
const appIconPath = isDev
? path.join(process.cwd(), 'build', 'icon.png')
: path.join(process.resourcesPath, 'build', 'icon.png')
@@ -15,6 +17,28 @@ function sendAppCommand(command: string): void {
mainWindow.webContents.send('ruwio:menu-command', command)
}
function parseUrl(raw: string): URL | null {
try {
return new URL(raw)
} catch {
return null
}
}
function isAllowedAppNavigation(raw: string): boolean {
const url = parseUrl(raw)
if (!url) return false
if (isDev) return url.origin === devServerOrigin
if (url.protocol !== 'file:') return false
const appEntry = path.join(app.getAppPath(), 'dist', 'index.html')
return path.normalize(fileURLToPath(url)) === path.normalize(appEntry)
}
function isAllowedExternalUrl(raw: string): boolean {
const url = parseUrl(raw)
return url?.protocol === 'https:'
}
function createMainWindow(): void {
mainWindow = new BrowserWindow({
width: 1280,
@@ -38,15 +62,14 @@ function createMainWindow(): void {
})
mainWindow.webContents.setWindowOpenHandler(({ url }: { url: string }) => {
if (url.startsWith('https://') || url.startsWith('http://')) {
if (isAllowedExternalUrl(url)) {
void shell.openExternal(url)
}
return { action: 'deny' }
})
mainWindow.webContents.on('will-navigate', (event: Event, url: string) => {
const allowedUrl = isDev ? devServerUrl : `file://${path.join(app.getAppPath(), 'dist', 'index.html')}`
if (!url.startsWith(allowedUrl)) {
if (!isAllowedAppNavigation(url)) {
event.preventDefault()
}
})