From 8e852286b55b89d68615e2ba483b23ec6a4620d2 Mon Sep 17 00:00:00 2001 From: zerob13 Date: Sat, 14 Feb 2026 14:48:14 +0800 Subject: [PATCH] fix(preload): add URL protocol filter for openExternal --- build/entitlements.mac.plist | 2 -- src/preload/index.ts | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/build/entitlements.mac.plist b/build/entitlements.mac.plist index b99bb8eca..970f16df9 100644 --- a/build/entitlements.mac.plist +++ b/build/entitlements.mac.plist @@ -6,8 +6,6 @@ com.apple.security.cs.allow-unsigned-executable-memory - com.apple.security.cs.allow-dyld-environment-variables - com.apple.security.files.user-selected.read-write com.apple.security.files.user-selected.read-only diff --git a/src/preload/index.ts b/src/preload/index.ts index b4672fa4b..b789aba1b 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -10,6 +10,17 @@ import { } from 'electron' import { exposeElectronAPI } from '@electron-toolkit/preload' +const ALLOWED_PROTOCOLS = ['http:', 'https:', 'mailto:', 'tel:', 'deepchat:'] + +const isValidExternalUrl = (url: string): boolean => { + try { + const parsed = new URL(url) + return ALLOWED_PROTOCOLS.includes(parsed.protocol.toLowerCase()) + } catch { + return false + } +} + // Cache variables let cachedWindowId: number | undefined = undefined let cachedWebContentsId: number | undefined = undefined @@ -44,6 +55,10 @@ const api = { return cachedWebContentsId }, openExternal: (url: string) => { + if (!isValidExternalUrl(url)) { + console.warn('Preload: Blocked openExternal for disallowed URL:', url) + return Promise.reject(new Error('URL protocol not allowed')) + } return shell.openExternal(url) }, toRelativePath: (filePath: string, baseDir?: string) => {