Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions patches/backported-patches.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,17 @@
"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 <pre> 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-70334",
"affected_versions": "< 1.136.2",
"patch_path": "patches/common/fix-config-nested-restricted-settings.diff",
"link": "https://github.com/microsoft/vscode/commit/0684cb5905a3f23156f45a28135326e09310ff4d"
},
{
"finding_id": "GHSA-q2f8-hh8x-wpc2",
"affected_versions": "< 1.136.2",
"patch_path": "patches/common/fix-config-nested-restricted-settings.diff",
"link": "https://github.com/microsoft/vscode/commit/0684cb5905a3f23156f45a28135326e09310ff4d"
}
]
77 changes: 77 additions & 0 deletions patches/common/fix-config-nested-restricted-settings.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
From: Sandeep Somavarapu <sasomava@microsoft.com>
Subject: Filter restricted settings in nested configuration objects
Origin: upstream, https://github.com/microsoft/vscode/commit/0684cb5905a3f23156f45a28135326e09310ff4d
Bug: GHSA-q2f8-hh8x-wpc2

ConfigurationModelParser only checked top-level keys against the
configuration registry. Walk nested objects and check each setting by its
effective dotted path. Remove when Code-OSS is updated to >= 1.136.2.
Index: code-editor-src/src/vs/platform/configuration/common/configurationModels.ts
===================================================================
--- code-editor-src.orig/src/vs/platform/configuration/common/configurationModels.ts
+++ code-editor-src/src/vs/platform/configuration/common/configurationModels.ts
@@ -441,12 +441,11 @@ export class ConfigurationModelParser {
hasExcludedProperties = hasExcludedProperties || result.hasExcludedProperties;
restricted.push(...result.restricted);
} else {
- const propertySchema = configurationProperties[key];
- if (propertySchema?.restricted) {
- restricted.push(key);
- }
- if (this.shouldInclude(key, propertySchema, excludedConfigurationProperties, options)) {
- raw[key] = properties[key];
+ const result = this.filterProperty(key, properties[key], configurationProperties, excludedConfigurationProperties, options);
+ restricted.push(...result.restricted);
+ hasExcludedProperties = hasExcludedProperties || result.hasExcludedProperties;
+ if (result.included) {
+ raw[key] = result.value;
} else {
hasExcludedProperties = true;
}
@@ -455,6 +454,46 @@ export class ConfigurationModelParser {
return { raw, restricted, hasExcludedProperties };
}

+ private filterProperty(path: string, value: unknown, configurationProperties: IStringDictionary<IRegisteredConfigurationPropertySchema>, excludedConfigurationProperties: IStringDictionary<IRegisteredConfigurationPropertySchema>, options: ConfigurationParseOptions): { included: boolean; value: unknown; restricted: string[]; hasExcludedProperties: boolean } {
+ const propertySchema = configurationProperties[path];
+ if (propertySchema) {
+ return { included: this.shouldInclude(path, propertySchema, excludedConfigurationProperties, options), value, restricted: propertySchema.restricted ? [path] : [], hasExcludedProperties: false };
+ }
+ if (!types.isObject(value) || Array.isArray(value)) {
+ return { included: this.shouldInclude(path, propertySchema, excludedConfigurationProperties, options), value, restricted: [], hasExcludedProperties: false };
+ }
+ // Excluded properties can themselves be object-typed (e.g. `mcp.enterpriseManagedAuth.idp`), so treat them as a leaf too.
+ if (excludedConfigurationProperties[path]) {
+ return { included: this.shouldInclude(path, propertySchema, excludedConfigurationProperties, options), value, restricted: [], hasExcludedProperties: false };
+ }
+ // If the whole object is explicitly excluded, do not recurse into its children.
+ if (options.exclude?.includes(path)) {
+ return { included: false, value, restricted: [], hasExcludedProperties: false };
+ }
+ const keys = Object.keys(value);
+ if (keys.length === 0) {
+ return { included: this.shouldInclude(path, propertySchema, excludedConfigurationProperties, options), value, restricted: [], hasExcludedProperties: false };
+ }
+ const nested: IStringDictionary<unknown> = {};
+ const restricted: string[] = [];
+ let included = false;
+ let hasExcludedProperties = false;
+ for (const key of keys) {
+ const result = this.filterProperty(`${path}.${key}`, (value as IStringDictionary<unknown>)[key], configurationProperties, excludedConfigurationProperties, options);
+ if (result.restricted.length) {
+ restricted.push(...result.restricted);
+ }
+ hasExcludedProperties = hasExcludedProperties || result.hasExcludedProperties;
+ if (result.included) {
+ nested[key] = result.value;
+ included = true;
+ } else {
+ hasExcludedProperties = true;
+ }
+ }
+ return { included, value: nested, restricted, hasExcludedProperties };
+ }
+
private shouldInclude(key: string, propertySchema: IConfigurationPropertySchema | undefined, excludedConfigurationProperties: IStringDictionary<IRegisteredConfigurationPropertySchema>, options: ConfigurationParseOptions): boolean {
if (options.exclude?.includes(key)) {
return false;
1 change: 1 addition & 0 deletions patches/sagemaker.series
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@ 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-config-nested-restricted-settings.diff
1 change: 1 addition & 0 deletions patches/web-embedded-with-terminal.series
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ 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-config-nested-restricted-settings.diff
1 change: 1 addition & 0 deletions patches/web-embedded.series
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@ 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-config-nested-restricted-settings.diff
1 change: 1 addition & 0 deletions patches/web-server.series
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ 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-config-nested-restricted-settings.diff
Loading