diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx index f67559a0238..f1c72441096 100644 --- a/packages/app/src/app.tsx +++ b/packages/app/src/app.tsx @@ -39,26 +39,25 @@ declare global { } const defaultServerUrl = iife(() => { - // 1. Query parameter (highest priority) - const param = new URLSearchParams(document.location.search).get("url") - if (param) return param + // NOTE: The ?url= query parameter was intentionally removed due to CVE-2026-22813 (GHSA-c83v-7274-4vgp) + // Allowing arbitrary server URLs via query params enables XSS attacks on localhost:4096 - // 2. Configured server URL (from desktop settings) + // 1. Configured server URL (from desktop settings) if (window.__OPENCODE__?.serverUrl) return window.__OPENCODE__.serverUrl - // 3. Known production hosts -> localhost (same as upstream + shuv.ai) + // 2. Known production hosts -> localhost (same as upstream + shuv.ai) if (location.hostname.includes("opencode.ai") || location.hostname.includes("shuv.ai")) return "http://localhost:4096" - // 4. Desktop app (Tauri) with injected port + // 3. Desktop app (Tauri) with injected port if (window.__SHUVCODE__?.port) return `http://127.0.0.1:${window.__SHUVCODE__.port}` if (window.__OPENCODE__?.port) return `http://127.0.0.1:${window.__OPENCODE__.port}` - // 5. Dev mode -> same-origin so Vite proxy handles LAN access + CORS + // 4. Dev mode -> same-origin so Vite proxy handles LAN access + CORS if (import.meta.env.DEV) { return `http://${import.meta.env.VITE_OPENCODE_SERVER_HOST ?? "localhost"}:${import.meta.env.VITE_OPENCODE_SERVER_PORT ?? "4096"}` } - // 6. Default -> same origin (production web command) + // 5. Default -> same origin (production web command) return window.location.origin }) diff --git a/packages/app/src/utils/hosted.ts b/packages/app/src/utils/hosted.ts index 94c4c9b9c91..bdd004d4bf2 100644 --- a/packages/app/src/utils/hosted.ts +++ b/packages/app/src/utils/hosted.ts @@ -9,7 +9,11 @@ export function isHostedEnvironment(): boolean { /** * Checks if a ?url= query parameter was provided in the URL. - * This indicates the user is trying to connect to a specific server. + * + * SECURITY WARNING: This function exists ONLY for display purposes (e.g., showing + * "Could not connect to X" in welcome-screen.tsx). The ?url= parameter must NEVER + * be used to determine actual server connections due to CVE-2026-22813 (XSS vulnerability). + * Server URL is determined exclusively by app.tsx defaultServerUrl logic. */ export function hasUrlQueryParam(): boolean { if (typeof window === "undefined") return false @@ -18,6 +22,11 @@ export function hasUrlQueryParam(): boolean { /** * Gets the ?url= query parameter value if present. + * + * SECURITY WARNING: This function exists ONLY for display purposes (e.g., showing + * error messages with the attempted URL). The returned value must NEVER be used + * for actual server connections due to CVE-2026-22813 (XSS vulnerability). + * Server URL is determined exclusively by app.tsx defaultServerUrl logic. */ export function getUrlQueryParam(): string | null { if (typeof window === "undefined") return null diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 01714077268..2bd2d727e76 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -1122,11 +1122,6 @@ export function Prompt(props: PromptProps) { {keybind.print("command_list")} commands - - - {keybind.print("variant_cycle")} cycle variants - - diff --git a/script/sync/fork-features.json b/script/sync/fork-features.json index 1675aff2790..296e296baf4 100644 --- a/script/sync/fork-features.json +++ b/script/sync/fork-features.json @@ -120,6 +120,19 @@ "Session migration for linked worktrees" ], "note": "Upstream uses Project.sandboxes array to track worktrees. Main worktree is always Project.worktree." + }, + { + "pr": "CVE-2026-22813", + "title": "Query parameter server URL override", + "author": "fork", + "removedDate": "2026-01-12", + "reason": "Critical XSS vulnerability (GHSA-c83v-7274-4vgp, CVE-2026-22813) - malicious websites could execute commands via ?url= parameter. Upstream fixed in v1.1.10 by removing this feature.", + "filesModified": ["packages/app/src/app.tsx"], + "codeRemoved": [ + "const param = new URLSearchParams(document.location.search).get('url')", + "if (param) return param" + ], + "note": "The ?url= query parameter allowed arbitrary server URL override, enabling XSS on localhost:4096. Attackers could inject malicious server URLs that return XSS payloads, then use /pty/ API to execute arbitrary commands." } ], "apiDependencies": [