From e056044ab5e30f790c9f6731b6c5c6634c3dc547 Mon Sep 17 00:00:00 2001 From: AboMeezO Date: Sat, 13 Jun 2026 12:48:38 +0300 Subject: [PATCH 1/3] fix: validate external URLs before opening --- electron/ipc/handlers.js | 23 ++++++++++++++++++++++- electron/main.js | 9 +++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/electron/ipc/handlers.js b/electron/ipc/handlers.js index 6487669..7dfcd7c 100644 --- a/electron/ipc/handlers.js +++ b/electron/ipc/handlers.js @@ -68,6 +68,21 @@ const appLauncher = new AutoLaunch({ path: process.execPath, }); +const ALLOWED_EXTERNAL_URL_PROTOCOLS = new Set(["http:", "https:", "mailto:"]); + +export const validateExternalUrl = (url) => { + if (typeof url !== "string" || url.trim() !== url || url.length === 0) { + return null; + } + + try { + const parsed = new URL(url); + return ALLOWED_EXTERNAL_URL_PROTOCOLS.has(parsed.protocol) ? parsed.toString() : null; + } catch { + return null; + } +}; + /** * Create a filesystem-safe filename segment for Windows/macOS/Linux. * Removes characters that are invalid on Windows and trims length. @@ -871,7 +886,13 @@ export const registerHandlers = () => { // Open external URL in default browser ipcMain.handle("app:openExternal", async (_, url) => { try { - await shell.openExternal(url); + const safeUrl = validateExternalUrl(url); + if (!safeUrl) { + logger.warn(`Blocked unsafe external URL: ${String(url).slice(0, 200)}`); + return false; + } + + await shell.openExternal(safeUrl); return true; } catch (error) { logger.error(`Failed to open external URL ${url}:`, error); diff --git a/electron/main.js b/electron/main.js index ee21d86..955a9c6 100644 --- a/electron/main.js +++ b/electron/main.js @@ -2,7 +2,7 @@ import { app, BrowserWindow, ipcMain, shell, protocol, net } from "electron"; import path from "path"; import fs from "fs"; import { fileURLToPath, pathToFileURL } from "url"; -import { registerHandlers } from "./ipc/handlers.js"; +import { registerHandlers, validateExternalUrl } from "./ipc/handlers.js"; import { initializeDatabase } from "./services/database.js"; import { initTray } from "./tray/tray.js"; import { stopAllProjects } from "./services/projectsManager.js"; @@ -168,7 +168,12 @@ async function createWindow() { mainWindow.webContents.send("window:unmaximize"); }); mainWindow.webContents.setWindowOpenHandler(({ url }) => { - shell.openExternal(url); + const safeUrl = validateExternalUrl(url); + if (safeUrl) { + shell.openExternal(safeUrl); + } else { + logger.warn(`Blocked unsafe window open URL: ${String(url).slice(0, 200)}`); + } return { action: "deny" }; }); From fd9ad349a8cec83934925be2ab76109fa65a22e3 Mon Sep 17 00:00:00 2001 From: AboMeezO Date: Sat, 13 Jun 2026 12:55:47 +0300 Subject: [PATCH 2/3] Handle external URL open errors --- electron/main.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/electron/main.js b/electron/main.js index 955a9c6..6d00d39 100644 --- a/electron/main.js +++ b/electron/main.js @@ -170,7 +170,9 @@ async function createWindow() { mainWindow.webContents.setWindowOpenHandler(({ url }) => { const safeUrl = validateExternalUrl(url); if (safeUrl) { - shell.openExternal(safeUrl); + shell.openExternal(safeUrl).catch((err) => { + logger.error(`Failed to open external URL: ${err.message}`); + }); } else { logger.warn(`Blocked unsafe window open URL: ${String(url).slice(0, 200)}`); } From bd7993b3ce435fa97683ae126c8d8e98cae67a62 Mon Sep 17 00:00:00 2001 From: AboMeezO Date: Sat, 13 Jun 2026 13:00:28 +0300 Subject: [PATCH 3/3] fix: use stable GitHub icon export --- src/pages/settings/AboutSection.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/settings/AboutSection.jsx b/src/pages/settings/AboutSection.jsx index a3b8b5a..eb8ed0b 100644 --- a/src/pages/settings/AboutSection.jsx +++ b/src/pages/settings/AboutSection.jsx @@ -4,7 +4,7 @@ import { motion } from "framer-motion"; import { Terminal, Globe, - Github, + GithubIcon, MessageCircle, Users, Mail, @@ -35,7 +35,7 @@ const LINKS = [ label: "GitHub", value: "DevRoots-Studio / SelfHost-Helper", href: "https://github.com/DevRoots-Studio/SelfHost-Helper", - Icon: Github, + Icon: GithubIcon, accent: "bg-white/8 text-foreground/80", badge: "Open Source", },