From a4f90e48757c18284fd04438f547fcd2362e101e Mon Sep 17 00:00:00 2001 From: Tristen Pierson Date: Mon, 4 May 2026 09:16:33 -0400 Subject: [PATCH] security: resolve 17 CodeQL alerts (XSS / attribute-sanitization / insecure-randomness / shell-quote) This is a defence-in-depth pass that closes every open CodeQL finding on the develop branch. No user-visible behaviour changes. media/session.js - esc() now also escapes " and ' so it is safe to use in HTML attribute context, not just element text. This fixes the underlying cause of the five js/incomplete-html-attribute-sanitization alerts at lines 104, 166, 172, 218, 299. - addU / addA: pass customTs (history-replay timestamps) through esc() before interpolating into innerHTML (was bare). - addTStart: escape lbl and the args.path branch of hint (was bare). These were the user-controlled values flagged by js/xss at line 78. - addImg: escape u (the data: URL / file path) before interpolating into . Closes the js/xss alert at line 298. - vcs_state additions/deletions span: coerce to integers via Number(x)|0 before HTML concat; closes the js/xss alert at line 510. - The Report Bug + View Full + Crash buttons used inline onclick="rptTool(this,'X','Y')" with brittle JS-string escaping via cleanR.replace(/'/g,"\\'") -> CodeQL flagged the regex pair as js/identity-replacement and the surrounding template as js/incomplete-html-attribute-sanitization. Replaced with data-action / data-tool / data-output / data-text / data-title / data-detail / data-repo attributes (HTML-escaped via esc()) plus one delegated document.addEventListener('click',...) handler that routes by btn.dataset.action. The brittle regex is gone; values cross the JS boundary as plain DOM attributes. src/ChatStreamConsumer.ts - generateSessionId() now uses crypto.randomUUID() instead of Math.random(); the 12-char hex slice is preserved so log lines remain readable. Closes both js/insecure-randomness alerts. src/extension.ts (specsmith.runPreflight) and src/GovernancePanel.ts (case 'agentTask') - The double-quoted shell argument was previously built with utterance.replace(/"/g,'\\"') which leaves a trailing backslash able to escape the closing quote. Now backslashes are escaped first, then double quotes. Closes both js/incomplete-sanitization alerts. src/test/session-logic.test.ts - The two integrity tests that scan the bundle for stray escaped backticks used /