From 0572bd5969af8d31042e32437f5d6e9b88e95db3 Mon Sep 17 00:00:00 2001 From: cavidelizade Date: Fri, 17 Jul 2026 00:07:41 +0400 Subject: [PATCH] fix(ui): sanitize external quicklink URLs The home page rendered a quicklink's stored URL straight into the anchor href, so a javascript: URL would run when clicked. Every other link surface already runs through safeUrl; the quicklink anchor was the exception (the favicon, copy and open-in-new-tab paths were fine). Route the external href through safeUrl so only http/https/mailto get through. Closes #327 Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/web/src/pages/WorkspaceHomePage.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/web/src/pages/WorkspaceHomePage.tsx b/apps/web/src/pages/WorkspaceHomePage.tsx index 383bf23..e72a0bd 100644 --- a/apps/web/src/pages/WorkspaceHomePage.tsx +++ b/apps/web/src/pages/WorkspaceHomePage.tsx @@ -10,6 +10,7 @@ import { stickiesService } from '../services/stickiesService'; import { StickyNoteCard } from '../components/stickies/StickyNoteCard'; import { pickRandomStickyBackground } from '../components/stickies/stickyPalette'; import { OPEN_HOME_WIDGETS } from '../lib/homeWidgetsEvents'; +import { safeUrl } from '../lib/sanitize'; import { recentsService } from '../services/recentsService'; import { useDocumentTitle } from '../hooks/useDocumentTitle'; import type { @@ -425,7 +426,9 @@ function QuicklinkCardRow({ const menuRootRef = useRef(null); const label = ql.title?.trim() || ql.url; const isInternal = !!ql.project_id; - const href = isInternal ? `${baseUrl}/projects/${ql.project_id}` : ql.url; + // External quicklink URLs are user-supplied, so run them through safeUrl to + // block javascript:/data: and other non http(s) schemes. + const href = isInternal ? `${baseUrl}/projects/${ql.project_id}` : safeUrl(ql.url); useEffect(() => { if (!menuOpen) return;