From 9fb21e16b49a89b228137fa5d4e20d9467aa54a9 Mon Sep 17 00:00:00 2001 From: Anastasiia Derendeeva Date: Thu, 13 Aug 2026 15:59:17 +0000 Subject: [PATCH] Backport VS Code 1.132.1 security fixes (9 advisories) Backports the microsoft/vscode 1.132.1 security fixes (PR #330308) to the pinned 1.119.1 source, clearing the GitHub Security Advisories scan failure (ticket V2322571997). Patched (4 patches, 6 CVEs): - fix-block-privileged-url-payload.diff: CVE-2026-70336, CVE-2026-69320 (fileless RCE via URL-controlled NODE_OPTIONS in web remote terminal / environmentService) - fix-terminal-workspace-trust-bypass.diff: CVE-2026-69278 (terminal Workspace Trust bypass via waitOnExit) - fix-network-filter-domain-validation.diff: CVE-2026-58650, CVE-2026-69306 (extensions.json terminal RCE; agent network filter bypass via IPv4-mapped IPv6 literals) - fix-buffer-copy-extensions.diff: CVE-2026-47285 (information disclosure via shared buffers) Marked N/A (3 CVEs, not present in Code Editor web/reh-web builds): - CVE-2026-65675, CVE-2026-70335: Copilot (stripped via disable-copilot-features.diff) - CVE-2026-59113: webContentExtractor webPageLoader is electron-main only All finding IDs (CVE + GHSA) registered in backported-patches.json. Verified: patches apply cleanly on all 4 targets; advisory scan reports 0 concerning advisories. --- patches/backported-patches.json | 114 +++++++++++++ .../fix-block-privileged-url-payload.diff | 109 +++++++++++++ .../common/fix-buffer-copy-extensions.diff | 47 ++++++ .../fix-network-filter-domain-validation.diff | 151 ++++++++++++++++++ .../fix-terminal-workspace-trust-bypass.diff | 28 ++++ patches/sagemaker.series | 4 + patches/web-embedded-with-terminal.series | 4 + patches/web-embedded.series | 4 + patches/web-server.series | 4 + 9 files changed, 465 insertions(+) create mode 100644 patches/common/fix-block-privileged-url-payload.diff create mode 100644 patches/common/fix-buffer-copy-extensions.diff create mode 100644 patches/common/fix-network-filter-domain-validation.diff create mode 100644 patches/common/fix-terminal-workspace-trust-bypass.diff diff --git a/patches/backported-patches.json b/patches/backported-patches.json index e8afbd4..0770a6e 100644 --- a/patches/backported-patches.json +++ b/patches/backported-patches.json @@ -88,5 +88,119 @@ "patch_path": "N/A", "link": "https://github.com/microsoft/vscode/commit/bc2d56c6f8da22a4bd31f741fcb034208770f158", "note": "Notebook Restricted-Mode bypass via mermaid render. Upstream vulnerable file extensions/mermaid-markdown-features/preview-src/notebook/index.ts (the 'temp.innerHTML = result' sink and renderMermaidBlocksInElement) does not exist in this branch's shipped source. The only mermaid extension here, mermaid-chat-features, renders diagrams via escapeHtmlText() into a
 and uses textContent (chat-webview-src/mermaidWebview.ts) inside a sandboxed webview with strict nonce CSP - no innerHTML of untrusted content. The markdown-language-features notebook renderer already sanitizes untrusted HTML with DOMPurify. No equivalent vulnerable innerHTML/insertAdjacentHTML sink for untrusted render output exists."
+  },
+  {
+    "finding_id": "CVE-2026-70336",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-block-privileged-url-payload.diff",
+    "link": "https://github.com/microsoft/vscode/commit/ef3ccf912287348aafd04dc6cc2c5619d6ccb70f"
+  },
+  {
+    "finding_id": "GHSA-fp6w-v29h-43rj",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-block-privileged-url-payload.diff",
+    "link": "https://github.com/microsoft/vscode/commit/ef3ccf912287348aafd04dc6cc2c5619d6ccb70f"
+  },
+  {
+    "finding_id": "CVE-2026-69320",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-block-privileged-url-payload.diff",
+    "link": "https://github.com/microsoft/vscode/commit/ef3ccf912287348aafd04dc6cc2c5619d6ccb70f"
+  },
+  {
+    "finding_id": "GHSA-h29r-p8vr-4vfm",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-block-privileged-url-payload.diff",
+    "link": "https://github.com/microsoft/vscode/commit/ef3ccf912287348aafd04dc6cc2c5619d6ccb70f"
+  },
+  {
+    "finding_id": "CVE-2026-69278",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-terminal-workspace-trust-bypass.diff",
+    "link": "https://github.com/microsoft/vscode/commit/3154a68fc151bcafe371f89d197412645e6a7616"
+  },
+  {
+    "finding_id": "GHSA-h9j4-x76r-fvj4",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-terminal-workspace-trust-bypass.diff",
+    "link": "https://github.com/microsoft/vscode/commit/3154a68fc151bcafe371f89d197412645e6a7616"
+  },
+  {
+    "finding_id": "CVE-2026-58650",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-network-filter-domain-validation.diff",
+    "link": "https://github.com/microsoft/vscode/commit/06a2bc84d0555f4c7ebd176809673e61fa49c6ff"
+  },
+  {
+    "finding_id": "GHSA-h6v9-3cqc-v234",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-network-filter-domain-validation.diff",
+    "link": "https://github.com/microsoft/vscode/commit/06a2bc84d0555f4c7ebd176809673e61fa49c6ff"
+  },
+  {
+    "finding_id": "CVE-2026-47285",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-buffer-copy-extensions.diff",
+    "link": "https://github.com/microsoft/vscode/commit/ae7a28076f3076a10bd07b49cf7ff730c1773e61"
+  },
+  {
+    "finding_id": "GHSA-vcpf-2mpp-vx3v",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-buffer-copy-extensions.diff",
+    "link": "https://github.com/microsoft/vscode/commit/ae7a28076f3076a10bd07b49cf7ff730c1773e61"
+  },
+  {
+    "finding_id": "CVE-2026-65675",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "N/A",
+    "link": "https://github.com/advisories/GHSA-3hjg-cwxj-qfc6",
+    "note": "Copilot Chat security feature bypass - Copilot not present in Code Editor"
+  },
+  {
+    "finding_id": "GHSA-3hjg-cwxj-qfc6",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "N/A",
+    "link": "https://github.com/advisories/GHSA-3hjg-cwxj-qfc6",
+    "note": "Copilot Chat security feature bypass - Copilot not present in Code Editor"
+  },
+  {
+    "finding_id": "CVE-2026-70335",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "N/A",
+    "link": "https://github.com/advisories/GHSA-w79w-rj9h-vg4f",
+    "note": "Copilot Custom Agent Hook RCE - Copilot not present in Code Editor"
+  },
+  {
+    "finding_id": "GHSA-w79w-rj9h-vg4f",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "N/A",
+    "link": "https://github.com/advisories/GHSA-w79w-rj9h-vg4f",
+    "note": "Copilot Custom Agent Hook RCE - Copilot not present in Code Editor"
+  },
+  {
+    "finding_id": "CVE-2026-59113",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "N/A",
+    "link": "https://github.com/advisories/GHSA-36qf-jgq9-4m6j",
+    "note": "Fetch Web Page OS protocol handler RCE - webContentExtractor is electron-main only, not present in Code Editor web/reh-web builds"
+  },
+  {
+    "finding_id": "GHSA-36qf-jgq9-4m6j",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "N/A",
+    "link": "https://github.com/advisories/GHSA-36qf-jgq9-4m6j",
+    "note": "Fetch Web Page OS protocol handler RCE - webContentExtractor is electron-main only, not present in Code Editor web/reh-web builds"
+  },
+  {
+    "finding_id": "CVE-2026-69306",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-network-filter-domain-validation.diff",
+    "link": "https://github.com/microsoft/vscode/commit/af3a976e194030a94f6bfb5aebc5e0f4d66f5e41"
+  },
+  {
+    "finding_id": "GHSA-6xp2-9cj3-f488",
+    "affected_versions": "< 1.132.1",
+    "patch_path": "patches/common/fix-network-filter-domain-validation.diff",
+    "link": "https://github.com/microsoft/vscode/commit/af3a976e194030a94f6bfb5aebc5e0f4d66f5e41"
   }
 ]
diff --git a/patches/common/fix-block-privileged-url-payload.diff b/patches/common/fix-block-privileged-url-payload.diff
new file mode 100644
index 0000000..7f6d5e2
--- /dev/null
+++ b/patches/common/fix-block-privileged-url-payload.diff
@@ -0,0 +1,109 @@
+Block privileged URL payload options in server
+
+Prevents environment variable injection via startParamsEnv by ensuring
+VSCODE_* critical vars cannot be overridden, sanitizes resolverEnv before
+use in terminal channel, removes dangerous env vars case-insensitively
+across all platforms, and restricts extension dev payload options to
+non-production builds only.
+
+Remove when Code-OSS is updated to >= 1.132.1.
+
+@backported: https://github.com/microsoft/vscode/commit/ef3ccf912287348aafd04dc6cc2c5619d6ccb70f
+@finding-id: CVE-2026-70336 GHSA-fp6w-v29h-43rj CVE-2026-69320 GHSA-h29r-p8vr-4vfm
+Index: b/src/vs/base/common/processes.ts
+===================================================================
+--- a/src/vs/base/common/processes.ts
++++ b/src/vs/base/common/processes.ts
+@@ -3,7 +3,7 @@
+  *  Licensed under the MIT License. See License.txt in the project root for license information.
+  *--------------------------------------------------------------------------------------------*/
+ 
+-import { IProcessEnvironment, isLinux } from './platform.js';
++import { IProcessEnvironment } from './platform.js';
+ 
+ /**
+  * Options to be passed to the external program or shell.
+@@ -136,13 +136,16 @@ export function removeDangerousEnvVariab
+ 		return;
+ 	}
+ 
+-	// Unset `DEBUG`, as an invalid value might lead to process crashes
+-	// See https://github.com/microsoft/vscode/issues/130072
+-	delete env['DEBUG'];
+-
+-	if (isLinux) {
+-		// Unset `LD_PRELOAD`, as it might lead to process crashes
+-		// See https://github.com/microsoft/vscode/issues/134177
+-		delete env['LD_PRELOAD'];
++	const dangerousEnvVariables = new Set([
++		'DEBUG',
++		'NODE_OPTIONS',
++		'VSCODE_NODE_OPTIONS',
++		'LD_PRELOAD',
++		'DYLD_INSERT_LIBRARIES'
++	]);
++	for (const key of Object.keys(env)) {
++		if (dangerousEnvVariables.has(key.toUpperCase())) {
++			delete env[key];
++		}
+ 	}
+ }
+Index: b/src/vs/server/node/extensionHostConnection.ts
+===================================================================
+--- a/src/vs/server/node/extensionHostConnection.ts
++++ b/src/vs/server/node/extensionHostConnection.ts
+@@ -40,12 +40,10 @@ export async function buildUserEnvironme
+ 	const env: IProcessEnvironment = {
+ 		...processEnv,
+ 		...userShellEnv,
+-		...{
+-			VSCODE_ESM_ENTRYPOINT: 'vs/workbench/api/node/extensionHostProcess',
+-			VSCODE_HANDLES_UNCAUGHT_ERRORS: 'true',
+-			VSCODE_NLS_CONFIG: JSON.stringify(nlsConfig)
+-		},
+-		...startParamsEnv
++		...startParamsEnv,
++		VSCODE_ESM_ENTRYPOINT: 'vs/workbench/api/node/extensionHostProcess',
++		VSCODE_HANDLES_UNCAUGHT_ERRORS: 'true',
++		VSCODE_NLS_CONFIG: JSON.stringify(nlsConfig)
+ 	};
+ 
+ 	const binFolder = environmentService.isBuilt ? join(environmentService.appRoot, 'bin') : join(environmentService.appRoot, 'resources', 'server', 'bin-dev');
+Index: b/src/vs/server/node/remoteTerminalChannel.ts
+===================================================================
+--- a/src/vs/server/node/remoteTerminalChannel.ts
++++ b/src/vs/server/node/remoteTerminalChannel.ts
+@@ -9,6 +9,7 @@ import { cloneAndChange } from '../../ba
+ import { Disposable } from '../../base/common/lifecycle.js';
+ import * as path from '../../base/common/path.js';
+ import * as platform from '../../base/common/platform.js';
++import { removeDangerousEnvVariables } from '../../base/common/processes.js';
+ import { URI } from '../../base/common/uri.js';
+ import { IURITransformer } from '../../base/common/uriIpc.js';
+ import { IServerChannel } from '../../base/parts/ipc/common/ipc.js';
+@@ -210,7 +211,9 @@ export class RemoteTerminalChannel exten
+ 		};
+ 
+ 
+-		const baseEnv = await buildUserEnvironment(args.resolverEnv, !!args.shellLaunchConfig.useShellEnvironment, platform.language, this._environmentService, this._logService, this._configurationService);
++		const resolverEnv = { ...args.resolverEnv };
++		removeDangerousEnvVariables(resolverEnv);
++		const baseEnv = await buildUserEnvironment(resolverEnv, !!args.shellLaunchConfig.useShellEnvironment, platform.language, this._environmentService, this._logService, this._configurationService);
+ 		this._logService.trace('baseEnv', baseEnv);
+ 
+ 		const reviveWorkspaceFolder = (workspaceData: IWorkspaceFolderData): IWorkspaceFolder => {
+Index: b/src/vs/workbench/services/environment/browser/environmentService.ts
+===================================================================
+--- a/src/vs/workbench/services/environment/browser/environmentService.ts
++++ b/src/vs/workbench/services/environment/browser/environmentService.ts
+@@ -302,8 +302,8 @@ export class BrowserWorkbenchEnvironment
+ 			extensionDevelopmentKind: undefined
+ 		};
+ 
+-		// Fill in selected extra environmental properties
+-		if (this.payload) {
++		// Extension host development options from the payload are only valid in development builds.
++		if (this.payload && !this.isBuilt) {
+ 			for (const [key, value] of this.payload) {
+ 				switch (key) {
+ 					case 'extensionDevelopmentPath':
diff --git a/patches/common/fix-buffer-copy-extensions.diff b/patches/common/fix-buffer-copy-extensions.diff
new file mode 100644
index 0000000..add9671
--- /dev/null
+++ b/patches/common/fix-buffer-copy-extensions.diff
@@ -0,0 +1,47 @@
+Always return copies of buffers to extensions
+
+Returns a copied slice of the buffer in extHostCommands instead of
+the original backing ArrayBuffer, preventing extensions from mutating
+shared memory. Also simplifies webview stream chunk handling to use
+VSBuffer.buffer which already returns a safe Uint8Array copy.
+
+Remove when Code-OSS is updated to >= 1.132.1.
+
+@backported: https://github.com/microsoft/vscode/commit/ae7a28076f3076a10bd07b49cf7ff730c1773e61
+@finding-id: CVE-2026-47285 GHSA-vcpf-2mpp-vx3v
+Index: b/src/vs/workbench/api/common/extHostCommands.ts
+===================================================================
+--- a/src/vs/workbench/api/common/extHostCommands.ts
++++ b/src/vs/workbench/api/common/extHostCommands.ts
+@@ -101,7 +101,8 @@ export class ExtHostCommands implements
+ 							return extHostTypeConverter.location.to(obj);
+ 						}
+ 						if (obj instanceof VSBuffer) {
+-							return obj.buffer.buffer;
++							// Create a copy of the buffer since the original buffer is owned by the extension host and might be reused for other commands
++							return obj.buffer.buffer.slice(obj.buffer.byteOffset, obj.buffer.byteOffset + obj.buffer.byteLength);
+ 						}
+ 						if (!Array.isArray(obj)) {
+ 							return obj;
+Index: b/src/vs/workbench/contrib/webview/browser/webviewElement.ts
+===================================================================
+--- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts
++++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts
+@@ -820,7 +820,7 @@ export class WebviewElement extends Disp
+ 									onData: (chunk) => {
+ 										if (!closed) {
+ 											try {
+-												controller.enqueue(new Uint8Array(chunk.buffer.buffer as ArrayBuffer, chunk.buffer.byteOffset, chunk.buffer.byteLength));
++												controller?.enqueue(new Uint8Array(chunk.buffer));
+ 											} catch {
+ 												closed = true;
+ 												this._activeStreamControllers.delete(controller);
+@@ -861,7 +861,7 @@ export class WebviewElement extends Disp
+ 						});
+ 						listenStream(result.stream, {
+ 							onData: (chunk) => {
+-								const data = new Uint8Array(chunk.buffer.buffer, chunk.buffer.byteOffset, chunk.buffer.byteLength);
++								const data = new Uint8Array(chunk.buffer);
+ 								this._send('did-load-resource-chunk', { id, data }, [data.buffer]);
+ 							},
+ 							onError: () => {
diff --git a/patches/common/fix-network-filter-domain-validation.diff b/patches/common/fix-network-filter-domain-validation.diff
new file mode 100644
index 0000000..f2fd744
--- /dev/null
+++ b/patches/common/fix-network-filter-domain-validation.diff
@@ -0,0 +1,151 @@
+Fix network filter domain validation and extension URL handler
+
+Hardens the network filter domain matcher to properly canonicalize URI
+authorities (handling user info, ports, and IPv6 literals), blocks HTTP/HTTPS
+requests with unparseable domains instead of allowing them, and reorders the
+extension URL handler to invoke override handlers only after trust checks,
+preventing trust bypass via URL authority manipulation.
+
+Remove when Code-OSS is updated to >= 1.132.1.
+
+@backported: https://github.com/microsoft/vscode/commit/06a2bc84d0555f4c7ebd176809673e61fa49c6ff
+@finding-id: CVE-2026-58650 GHSA-h6v9-3cqc-v234 CVE-2026-69306 GHSA-6xp2-9cj3-f488
+Index: b/src/vs/platform/networkFilter/common/domainMatcher.ts
+===================================================================
+--- a/src/vs/platform/networkFilter/common/domainMatcher.ts
++++ b/src/vs/platform/networkFilter/common/domainMatcher.ts
+@@ -91,6 +91,25 @@ export function normalizeDomain(value: s
+ 	return hasWildcardPrefix ? `*.${host}` : host;
+ }
+ 
++function normalizeUriAuthority(authority: string | undefined): string | undefined {
++	if (!authority || /[/?#\\]/.test(authority)) {
++		return undefined;
++	}
++
++	let hostname: string;
++	try {
++		hostname = new URL(`http://${authority}`).hostname.toLowerCase();
++	} catch {
++		return undefined;
++	}
++
++	if (hostname.startsWith('[')) {
++		return hostname.endsWith(']') ? hostname : undefined;
++	}
++
++	return normalizeDomain(hostname, true);
++}
++
+ /**
+  * Extracts the domain portion from a pattern string.
+  * If the pattern contains `://`, it is parsed as a URI and the authority is returned.
+@@ -120,7 +139,8 @@ export function extractDomainPattern(pat
+  * @returns `true` if the domain matches the pattern.
+  */
+ export function matchesDomainPattern(domain: string, pattern: string): boolean {
+-	const normalizedPattern = normalizeDomain(extractDomainPattern(pattern), pattern.includes('://'));
++	const extractedPattern = extractDomainPattern(pattern);
++	const normalizedPattern = normalizeDomain(extractedPattern, pattern.includes('://')) ?? normalizeUriAuthority(extractedPattern);
+ 	if (!normalizedPattern) {
+ 		return false;
+ 	}
+@@ -136,13 +156,13 @@ export function matchesDomainPattern(dom
+ 
+ /**
+  * Extracts and normalizes a domain from a URI.
+- * Strips port numbers and trailing dots.
++ * Separates user information and ports, and canonicalizes IPv6 literals.
+  *
+  * @param uri The URI to extract the domain from.
+  * @returns The normalized domain, or `undefined` if no valid domain could be extracted.
+  */
+ export function extractDomainFromUri(uri: URI): string | undefined {
+-	return normalizeDomain(uri.authority, true);
++	return normalizeUriAuthority(uri.authority);
+ }
+ 
+ /**
+Index: b/src/vs/platform/networkFilter/common/networkFilterService.ts
+===================================================================
+--- a/src/vs/platform/networkFilter/common/networkFilterService.ts
++++ b/src/vs/platform/networkFilter/common/networkFilterService.ts
+@@ -6,6 +6,7 @@
+ import { Emitter, Event } from '../../../base/common/event.js';
+ import { Disposable } from '../../../base/common/lifecycle.js';
+ import { LRUCache } from '../../../base/common/map.js';
++import { matchesScheme, Schemas } from '../../../base/common/network.js';
+ import { URI } from '../../../base/common/uri.js';
+ import { localize } from '../../../nls.js';
+ import { IConfigurationService } from '../../configuration/common/configuration.js';
+@@ -122,13 +123,13 @@ export class AgentNetworkFilterService e
+ 		}
+ 
+ 		// File URIs and URIs without authority always pass
+-		if (uri.scheme === 'file' || !uri.authority) {
++		if (matchesScheme(uri, Schemas.file) || !uri.authority) {
+ 			return true;
+ 		}
+ 
+ 		const domain = extractDomainFromUri(uri);
+ 		if (!domain) {
+-			return true;
++			return !matchesScheme(uri, Schemas.http) && !matchesScheme(uri, Schemas.https);
+ 		}
+ 
+ 		let result = this.domainCache.get(domain);
+Index: b/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts
+===================================================================
+--- a/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts
++++ b/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts
+@@ -156,27 +156,21 @@ class ExtensionUrlHandler implements IEx
+ 		}
+ 
+ 		const overrideHandler = ExtensionUrlHandlerOverrideRegistry.getHandler(uri);
+-		if (overrideHandler) {
+-			const handled = await overrideHandler.handleURL(uri);
+-			if (handled) {
+-				return handled;
+-			}
+-		}
+-
+ 		const extensionId = uri.authority;
+ 
+ 		const initialHandler = this.extensionHandlers.get(ExtensionIdentifier.toKey(extensionId));
+ 		let extensionDisplayName: string;
++		let extensionInstalled = !!initialHandler;
+ 
+ 		if (!initialHandler) {
+ 			// The extension is not yet activated, so let's check if it is installed and enabled
+ 			const extension = await this.extensionService.getExtension(extensionId);
+-			if (!extension) {
++			extensionInstalled = !!extension;
++			if (!extension && !overrideHandler) {
+ 				await this.handleUnhandledURL(uri, extensionId, options);
+ 				return true;
+-			} else {
+-				extensionDisplayName = extension.displayName ?? '';
+ 			}
++			extensionDisplayName = extension?.displayName ?? extensionId;
+ 		} else {
+ 			extensionDisplayName = initialHandler.extensionDisplayName;
+ 		}
+@@ -215,6 +209,18 @@ class ExtensionUrlHandler implements IEx
+ 			}
+ 		}
+ 
++		if (overrideHandler) {
++			const handled = await overrideHandler.handleURL(uri);
++			if (handled) {
++				return handled;
++			}
++		}
++
++		if (!extensionInstalled) {
++			await this.handleUnhandledURL(uri, extensionId, { ...options, trusted: true });
++			return true;
++		}
++
+ 		const handler = this.extensionHandlers.get(ExtensionIdentifier.toKey(extensionId));
+ 
+ 		if (handler) {
diff --git a/patches/common/fix-terminal-workspace-trust-bypass.diff b/patches/common/fix-terminal-workspace-trust-bypass.diff
new file mode 100644
index 0000000..338add5
--- /dev/null
+++ b/patches/common/fix-terminal-workspace-trust-bypass.diff
@@ -0,0 +1,28 @@
+Fix terminal workspace trust bypass
+
+Adds missing return statements after _onProcessExit calls in the terminal
+trust and empty-workspace-cwd checks, preventing continued execution of
+_createProcess after the terminal should have been terminated.
+
+Remove when Code-OSS is updated to >= 1.132.1.
+
+@backported: https://github.com/microsoft/vscode/commit/3154a68fc151bcafe371f89d197412645e6a7616
+@finding-id: CVE-2026-69278 GHSA-h9j4-x76r-fvj4
+Index: b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
+===================================================================
+--- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
++++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
+@@ -1581,11 +1581,13 @@ export class TerminalInstance extends Di
+ 		// Allow remote and local terminals from remote to be created in untrusted remote workspace
+ 		if (!trusted && !this.remoteAuthority && !this._workbenchEnvironmentService.remoteAuthority) {
+ 			this._onProcessExit({ message: nls.localize('workspaceNotTrustedCreateTerminal', "Cannot launch a terminal process in an untrusted workspace") });
++			return;
+ 		} else if (this._workspaceContextService.getWorkspace().folders.length === 0 && this._cwd && this._userHome && normalizeDriveLetter(this._cwd) !== normalizeDriveLetter(this._userHome)) {
+ 			// something strange is going on if cwd is not userHome in an empty workspace
+ 			this._onProcessExit({
+ 				message: nls.localize('workspaceEmptyCreateTerminalCwd', "Cannot launch a terminal process in an empty workspace with cwd {0} different from userHome {1}", this._cwd, this._userHome)
+ 			});
++			return;
+ 		}
+ 		// Re-evaluate dimensions if the container has been set since the xterm instance was created
+ 		if (this._container && this._cols === 0 && this._rows === 0) {
diff --git a/patches/sagemaker.series b/patches/sagemaker.series
index ccfc8bf..f902236 100644
--- a/patches/sagemaker.series
+++ b/patches/sagemaker.series
@@ -72,3 +72,7 @@ common/finding-override-undici.diff
 common/finding-override-form-data.diff
 common/finding-override-tar.diff
 common/fix-copilot-debug-override-user-scope.diff
+common/fix-block-privileged-url-payload.diff
+common/fix-terminal-workspace-trust-bypass.diff
+common/fix-network-filter-domain-validation.diff
+common/fix-buffer-copy-extensions.diff
diff --git a/patches/web-embedded-with-terminal.series b/patches/web-embedded-with-terminal.series
index 4ea4488..8839ce0 100644
--- a/patches/web-embedded-with-terminal.series
+++ b/patches/web-embedded-with-terminal.series
@@ -68,3 +68,7 @@ common/fix-remote-hosts-loopback.diff
 common/finding-override-undici.diff
 common/finding-override-form-data.diff
 common/fix-copilot-debug-override-user-scope.diff
+common/fix-block-privileged-url-payload.diff
+common/fix-terminal-workspace-trust-bypass.diff
+common/fix-network-filter-domain-validation.diff
+common/fix-buffer-copy-extensions.diff
diff --git a/patches/web-embedded.series b/patches/web-embedded.series
index 721ea56..8873737 100644
--- a/patches/web-embedded.series
+++ b/patches/web-embedded.series
@@ -71,3 +71,7 @@ common/fix-remote-hosts-loopback.diff
 common/finding-override-undici.diff
 common/finding-override-form-data.diff
 common/fix-copilot-debug-override-user-scope.diff
+common/fix-block-privileged-url-payload.diff
+common/fix-terminal-workspace-trust-bypass.diff
+common/fix-network-filter-domain-validation.diff
+common/fix-buffer-copy-extensions.diff
diff --git a/patches/web-server.series b/patches/web-server.series
index 34bdd22..9f4c51e 100644
--- a/patches/web-server.series
+++ b/patches/web-server.series
@@ -50,3 +50,7 @@ common/fix-remote-hosts-loopback.diff
 common/finding-override-undici.diff
 common/finding-override-form-data.diff
 common/fix-copilot-debug-override-user-scope.diff
+common/fix-block-privileged-url-payload.diff
+common/fix-terminal-workspace-trust-bypass.diff
+common/fix-network-filter-domain-validation.diff
+common/fix-buffer-copy-extensions.diff